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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "ospf6_proto.h"
35 #include "ospf6_message.h"
36 #include "ospf6_route.h"
37 #include "ospf6_lsa.h"
38 #include "ospf6_lsdb.h"
40 #include "ospf6_top.h"
41 #include "ospf6_area.h"
42 #include "ospf6_interface.h"
43 #include "ospf6_neighbor.h"
44 #include "ospf6_intra.h"
45 #include "ospf6_asbr.h"
46 #include "ospf6_abr.h"
47 #include "ospf6_flood.h"
49 #include "ospf6_spf.h"
51 unsigned char conf_debug_ospf6_brouter
= 0;
52 u_int32_t conf_debug_ospf6_brouter_specific_router_id
;
53 u_int32_t conf_debug_ospf6_brouter_specific_area_id
;
55 /******************************/
56 /* RFC2740 3.4.3.1 Router-LSA */
57 /******************************/
60 ospf6_router_lsa_get_nbr_id (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
63 struct ospf6_router_lsa
*router_lsa
;
64 struct ospf6_router_lsdesc
*lsdesc
;
66 char buf1
[INET_ADDRSTRLEN
], buf2
[INET_ADDRSTRLEN
];
70 router_lsa
= (struct ospf6_router_lsa
*)
71 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
72 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
73 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
75 lsdesc
= (struct ospf6_router_lsdesc
*)
76 (start
+ pos
*(sizeof (struct ospf6_router_lsdesc
)));
77 if ((char *)lsdesc
< end
)
79 if (buf
&& (buflen
> INET_ADDRSTRLEN
*2))
81 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
83 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
85 sprintf (buf
, "%s/%s", buf2
, buf1
);
96 ospf6_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
98 char *start
, *end
, *current
;
99 char buf
[32], name
[32], bits
[16], options
[32];
100 struct ospf6_router_lsa
*router_lsa
;
101 struct ospf6_router_lsdesc
*lsdesc
;
103 router_lsa
= (struct ospf6_router_lsa
*)
104 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
106 ospf6_capability_printbuf (router_lsa
->bits
, bits
, sizeof (bits
));
107 ospf6_options_printbuf (router_lsa
->options
, options
, sizeof (options
));
108 vty_out (vty
, " Bits: %s Options: %s%s", bits
, options
, VNL
);
110 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
111 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
112 for (current
= start
; current
+ sizeof (struct ospf6_router_lsdesc
) <= end
;
113 current
+= sizeof (struct ospf6_router_lsdesc
))
115 lsdesc
= (struct ospf6_router_lsdesc
*) current
;
117 if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_POINTTOPOINT
)
118 snprintf (name
, sizeof (name
), "Point-To-Point");
119 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
)
120 snprintf (name
, sizeof (name
), "Transit-Network");
121 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_STUB_NETWORK
)
122 snprintf (name
, sizeof (name
), "Stub-Network");
123 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_VIRTUAL_LINK
)
124 snprintf (name
, sizeof (name
), "Virtual-Link");
126 snprintf (name
, sizeof (name
), "Unknown (%#x)", lsdesc
->type
);
128 vty_out (vty
, " Type: %s Metric: %d%s",
129 name
, ntohs (lsdesc
->metric
), VNL
);
130 vty_out (vty
, " Interface ID: %s%s",
131 inet_ntop (AF_INET
, &lsdesc
->interface_id
,
132 buf
, sizeof (buf
)), VNL
);
133 vty_out (vty
, " Neighbor Interface ID: %s%s",
134 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
135 buf
, sizeof (buf
)), VNL
);
136 vty_out (vty
, " Neighbor Router ID: %s%s",
137 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
138 buf
, sizeof (buf
)), VNL
);
144 ospf6_router_lsa_options_set (struct ospf6_area
*oa
,
145 struct ospf6_router_lsa
*router_lsa
)
147 OSPF6_OPT_CLEAR_ALL (router_lsa
->options
);
148 memcpy (router_lsa
->options
, oa
->options
, 3);
150 if (ospf6_is_router_abr (ospf6
))
151 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
153 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
155 if (!IS_AREA_STUB (oa
) && ospf6_asbr_is_asbr (oa
->ospf6
))
157 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
161 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
164 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_V
);
165 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_W
);
169 ospf6_router_is_stub_router (struct ospf6_lsa
*lsa
)
171 struct ospf6_router_lsa
*rtr_lsa
;
173 if (lsa
!= NULL
&& OSPF6_LSA_IS_TYPE (ROUTER
, lsa
))
175 rtr_lsa
= (struct ospf6_router_lsa
*)
176 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
178 if (!OSPF6_OPT_ISSET (rtr_lsa
->options
, OSPF6_OPT_R
))
180 return (OSPF6_IS_STUB_ROUTER
);
182 else if (!OSPF6_OPT_ISSET (rtr_lsa
->options
, OSPF6_OPT_V6
))
184 return (OSPF6_IS_STUB_ROUTER_V6
);
188 return (OSPF6_NOT_STUB_ROUTER
);
192 ospf6_router_lsa_originate (struct thread
*thread
)
194 struct ospf6_area
*oa
;
196 char buffer
[OSPF6_MAX_LSASIZE
];
197 struct ospf6_lsa_header
*lsa_header
;
198 struct ospf6_lsa
*lsa
;
200 u_int32_t link_state_id
= 0;
201 struct listnode
*node
, *nnode
;
203 struct ospf6_interface
*oi
;
204 struct ospf6_neighbor
*on
, *drouter
= NULL
;
205 struct ospf6_router_lsa
*router_lsa
;
206 struct ospf6_router_lsdesc
*lsdesc
;
211 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
212 oa
->thread_router_lsa
= NULL
;
214 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
215 zlog_debug ("Originate Router-LSA for Area %s", oa
->name
);
217 memset (buffer
, 0, sizeof (buffer
));
218 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
219 router_lsa
= (struct ospf6_router_lsa
*)
220 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
222 ospf6_router_lsa_options_set (oa
, router_lsa
);
224 /* describe links for each interfaces */
225 lsdesc
= (struct ospf6_router_lsdesc
*)
226 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
228 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
230 /* Interfaces in state Down or Loopback are not described */
231 if (oi
->state
== OSPF6_INTERFACE_DOWN
||
232 oi
->state
== OSPF6_INTERFACE_LOOPBACK
)
235 /* Nor are interfaces without any full adjacencies described */
237 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
238 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
244 /* Multiple Router-LSA instance according to size limit setting */
245 if ( (oa
->router_lsa_size_limit
!= 0)
246 && ((size_t)((char *)lsdesc
- buffer
)
247 + sizeof (struct ospf6_router_lsdesc
)
248 > oa
->router_lsa_size_limit
))
250 if ((caddr_t
) lsdesc
== (caddr_t
) router_lsa
+
251 sizeof (struct ospf6_router_lsa
))
253 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
254 zlog_debug ("Size limit setting for Router-LSA too short");
261 /* Point-to-Point interfaces */
262 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
264 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
266 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
269 lsdesc
->type
= OSPF6_ROUTER_LSDESC_POINTTOPOINT
;
270 lsdesc
->metric
= htons (oi
->cost
);
271 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
272 lsdesc
->neighbor_interface_id
= htonl (on
->ifindex
);
273 lsdesc
->neighbor_router_id
= on
->router_id
;
279 /* Broadcast and NBMA interfaces */
280 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
282 /* If this router is not DR,
283 and If this router not fully adjacent with DR,
284 this interface is not transit yet: ignore. */
285 if (oi
->state
!= OSPF6_INTERFACE_DR
)
287 drouter
= ospf6_neighbor_lookup (oi
->drouter
, oi
);
288 if (drouter
== NULL
|| drouter
->state
!= OSPF6_NEIGHBOR_FULL
)
292 lsdesc
->type
= OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
;
293 lsdesc
->metric
= htons (oi
->cost
);
294 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
295 if (oi
->state
!= OSPF6_INTERFACE_DR
)
297 lsdesc
->neighbor_interface_id
= htonl (drouter
->ifindex
);
298 lsdesc
->neighbor_router_id
= drouter
->router_id
;
302 lsdesc
->neighbor_interface_id
= htonl (oi
->interface
->ifindex
);
303 lsdesc
->neighbor_router_id
= oi
->area
->ospf6
->router_id
;
310 assert (0); /* Unknown interface type */
315 /* Point-to-Multipoint interfaces */
319 /* Fill LSA Header */
321 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
322 lsa_header
->id
= htonl (link_state_id
);
323 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
325 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
326 lsa_header
->adv_router
, oa
->lsdb
);
327 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
330 ospf6_lsa_checksum (lsa_header
);
333 lsa
= ospf6_lsa_create (lsa_header
);
336 ospf6_lsa_originate_area (lsa
, oa
);
340 /* Do premature-aging of rest, undesired Router-LSAs */
341 type
= ntohs (OSPF6_LSTYPE_ROUTER
);
342 router
= oa
->ospf6
->router_id
;
344 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, oa
->lsdb
); lsa
;
345 lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
347 if (ntohl (lsa
->header
->id
) < link_state_id
)
349 ospf6_lsa_purge (lsa
);
354 * Waiting till the LSA is actually removed from the database to trigger
355 * SPF delays network convergence. Unlike IPv4, for an ABR, when all
356 * interfaces associated with an area are gone, triggering an SPF right away
357 * helps convergence with inter-area routes.
359 if (count
&& !link_state_id
)
360 ospf6_spf_schedule (oa
->ospf6
, OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED
);
365 /*******************************/
366 /* RFC2740 3.4.3.2 Network-LSA */
367 /*******************************/
370 ospf6_network_lsa_get_ar_id (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
373 char *start
, *end
, *current
;
374 struct ospf6_network_lsa
*network_lsa
;
375 struct ospf6_network_lsdesc
*lsdesc
;
379 network_lsa
= (struct ospf6_network_lsa
*)
380 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
382 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
383 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
384 current
= start
+ pos
*(sizeof (struct ospf6_network_lsdesc
));
386 if ((current
+ sizeof(struct ospf6_network_lsdesc
)) <= end
)
388 lsdesc
= (struct ospf6_network_lsdesc
*)current
;
390 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, buflen
);
400 ospf6_network_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
402 char *start
, *end
, *current
;
403 struct ospf6_network_lsa
*network_lsa
;
404 struct ospf6_network_lsdesc
*lsdesc
;
405 char buf
[128], options
[32];
407 network_lsa
= (struct ospf6_network_lsa
*)
408 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
410 ospf6_options_printbuf (network_lsa
->options
, options
, sizeof (options
));
411 vty_out (vty
, " Options: %s%s", options
, VNL
);
413 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
414 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
415 for (current
= start
; current
+ sizeof (struct ospf6_network_lsdesc
) <= end
;
416 current
+= sizeof (struct ospf6_network_lsdesc
))
418 lsdesc
= (struct ospf6_network_lsdesc
*) current
;
419 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, sizeof (buf
));
420 vty_out (vty
, " Attached Router: %s%s", buf
, VNL
);
426 ospf6_network_lsa_originate (struct thread
*thread
)
428 struct ospf6_interface
*oi
;
430 char buffer
[OSPF6_MAX_LSASIZE
];
431 struct ospf6_lsa_header
*lsa_header
;
434 struct ospf6_lsa
*old
, *lsa
;
435 struct ospf6_network_lsa
*network_lsa
;
436 struct ospf6_network_lsdesc
*lsdesc
;
437 struct ospf6_neighbor
*on
;
438 struct ospf6_link_lsa
*link_lsa
;
442 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
443 oi
->thread_network_lsa
= NULL
;
445 /* The interface must be enabled until here. A Network-LSA of a
446 disabled interface (but was once enabled) should be flushed
447 by ospf6_lsa_refresh (), and does not come here. */
450 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK
),
451 htonl (oi
->interface
->ifindex
),
452 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
454 /* Do not originate Network-LSA if not DR */
455 if (oi
->state
!= OSPF6_INTERFACE_DR
)
459 ospf6_lsa_purge (old
);
461 * Waiting till the LSA is actually removed from the database to
462 * trigger SPF delays network convergence.
464 ospf6_spf_schedule (oi
->area
->ospf6
,
465 OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED
);
470 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
471 zlog_debug ("Originate Network-LSA for Interface %s", oi
->interface
->name
);
473 /* If none of neighbor is adjacent to us */
476 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
477 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
482 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
483 zlog_debug ("Interface stub, ignore");
485 ospf6_lsa_purge (old
);
490 memset (buffer
, 0, sizeof (buffer
));
491 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
492 network_lsa
= (struct ospf6_network_lsa
*)
493 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
495 /* Collect the interface's Link-LSAs to describe
496 network's optional capabilities */
497 type
= htons (OSPF6_LSTYPE_LINK
);
498 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
499 lsa
= ospf6_lsdb_type_next (type
, lsa
))
501 link_lsa
= (struct ospf6_link_lsa
*)
502 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
503 network_lsa
->options
[0] |= link_lsa
->options
[0];
504 network_lsa
->options
[1] |= link_lsa
->options
[1];
505 network_lsa
->options
[2] |= link_lsa
->options
[2];
508 lsdesc
= (struct ospf6_network_lsdesc
*)
509 ((caddr_t
) network_lsa
+ sizeof (struct ospf6_network_lsa
));
511 /* set Link Description to the router itself */
512 lsdesc
->router_id
= oi
->area
->ospf6
->router_id
;
515 /* Walk through the neighbors */
516 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
518 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
521 /* set this neighbor's Router-ID to LSA */
522 lsdesc
->router_id
= on
->router_id
;
526 /* Fill LSA Header */
528 lsa_header
->type
= htons (OSPF6_LSTYPE_NETWORK
);
529 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
530 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
532 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
533 lsa_header
->adv_router
, oi
->area
->lsdb
);
534 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
537 ospf6_lsa_checksum (lsa_header
);
540 lsa
= ospf6_lsa_create (lsa_header
);
543 ospf6_lsa_originate_area (lsa
, oi
->area
);
549 /****************************/
550 /* RFC2740 3.4.3.6 Link-LSA */
551 /****************************/
554 ospf6_link_lsa_get_prefix_str (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
557 char *start
, *end
, *current
;
558 struct ospf6_link_lsa
*link_lsa
;
560 struct ospf6_prefix
*prefix
;
561 int cnt
= 0, prefixnum
;
565 link_lsa
= (struct ospf6_link_lsa
*)
566 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
569 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, buflen
);
573 prefixnum
= ntohl (link_lsa
->prefix_num
);
577 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
578 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
583 prefix
= (struct ospf6_prefix
*) current
;
584 if (prefix
->prefix_length
== 0 ||
585 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
592 current
= start
+ pos
*OSPF6_PREFIX_SIZE(prefix
);
597 memset (&in6
, 0, sizeof (in6
));
598 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
599 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
600 inet_ntop (AF_INET6
, &in6
, buf
, buflen
);
603 } while (current
<= end
);
609 ospf6_link_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
611 char *start
, *end
, *current
;
612 struct ospf6_link_lsa
*link_lsa
;
614 char buf
[128], options
[32];
615 struct ospf6_prefix
*prefix
;
616 const char *p
, *mc
, *la
, *nu
;
619 link_lsa
= (struct ospf6_link_lsa
*)
620 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
622 ospf6_options_printbuf (link_lsa
->options
, options
, sizeof (options
));
623 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, sizeof (buf
));
624 prefixnum
= ntohl (link_lsa
->prefix_num
);
626 vty_out (vty
, " Priority: %d Options: %s%s",
627 link_lsa
->priority
, options
, VNL
);
628 vty_out (vty
, " LinkLocal Address: %s%s", buf
, VNL
);
629 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
631 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
632 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
633 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
635 prefix
= (struct ospf6_prefix
*) current
;
636 if (prefix
->prefix_length
== 0 ||
637 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
640 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
642 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
644 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
646 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
648 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
651 memset (&in6
, 0, sizeof (in6
));
652 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
653 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
654 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
655 vty_out (vty
, " Prefix: %s/%d%s",
656 buf
, prefix
->prefix_length
, VNL
);
663 ospf6_link_lsa_originate (struct thread
*thread
)
665 struct ospf6_interface
*oi
;
667 char buffer
[OSPF6_MAX_LSASIZE
];
668 struct ospf6_lsa_header
*lsa_header
;
669 struct ospf6_lsa
*old
, *lsa
;
671 struct ospf6_link_lsa
*link_lsa
;
672 struct ospf6_route
*route
;
673 struct ospf6_prefix
*op
;
675 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
676 oi
->thread_link_lsa
= NULL
;
680 /* find previous LSA */
681 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK
),
682 htonl (oi
->interface
->ifindex
),
683 oi
->area
->ospf6
->router_id
, oi
->lsdb
);
685 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
688 ospf6_lsa_purge (old
);
692 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
693 zlog_debug ("Originate Link-LSA for Interface %s", oi
->interface
->name
);
695 /* can't make Link-LSA if linklocal address not set */
696 if (oi
->linklocal_addr
== NULL
)
698 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
699 zlog_debug ("No Linklocal address on %s, defer originating",
700 oi
->interface
->name
);
702 ospf6_lsa_purge (old
);
707 memset (buffer
, 0, sizeof (buffer
));
708 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
709 link_lsa
= (struct ospf6_link_lsa
*)
710 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
713 link_lsa
->priority
= oi
->priority
;
714 memcpy (link_lsa
->options
, oi
->area
->options
, 3);
715 memcpy (&link_lsa
->linklocal_addr
, oi
->linklocal_addr
,
716 sizeof (struct in6_addr
));
717 link_lsa
->prefix_num
= htonl (oi
->route_connected
->count
);
719 op
= (struct ospf6_prefix
*)
720 ((caddr_t
) link_lsa
+ sizeof (struct ospf6_link_lsa
));
722 /* connected prefix to advertise */
723 for (route
= ospf6_route_head (oi
->route_connected
); route
;
724 route
= ospf6_route_next (route
))
726 op
->prefix_length
= route
->prefix
.prefixlen
;
727 op
->prefix_options
= route
->path
.prefix_options
;
728 op
->prefix_metric
= htons (0);
729 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
730 OSPF6_PREFIX_SPACE (op
->prefix_length
));
731 op
= OSPF6_PREFIX_NEXT (op
);
734 /* Fill LSA Header */
736 lsa_header
->type
= htons (OSPF6_LSTYPE_LINK
);
737 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
738 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
740 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
741 lsa_header
->adv_router
, oi
->lsdb
);
742 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) buffer
);
745 ospf6_lsa_checksum (lsa_header
);
748 lsa
= ospf6_lsa_create (lsa_header
);
751 ospf6_lsa_originate_interface (lsa
, oi
);
757 /*****************************************/
758 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
759 /*****************************************/
761 ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa
*lsa
, char *buf
,
764 char *start
, *end
, *current
;
765 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
767 int prefixnum
, cnt
= 0;
768 struct ospf6_prefix
*prefix
;
772 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
773 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
775 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
779 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
780 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
785 prefix
= (struct ospf6_prefix
*) current
;
786 if (prefix
->prefix_length
== 0 ||
787 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
794 current
= start
+ pos
*OSPF6_PREFIX_SIZE(prefix
);
799 memset (&in6
, 0, sizeof (in6
));
800 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
801 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
802 inet_ntop (AF_INET6
, &in6
, buf
, buflen
);
803 sprintf(&buf
[strlen(buf
)], "/%d", prefix
->prefix_length
);
806 } while (current
<= end
);
812 ospf6_intra_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
814 char *start
, *end
, *current
;
815 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
818 struct ospf6_prefix
*prefix
;
819 char id
[16], adv_router
[16];
820 const char *p
, *mc
, *la
, *nu
;
823 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
824 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
826 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
828 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
830 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_id
, id
, sizeof (id
));
831 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_adv_router
,
832 adv_router
, sizeof (adv_router
));
833 vty_out (vty
, " Reference: %s Id: %s Adv: %s%s",
834 ospf6_lstype_name (intra_prefix_lsa
->ref_type
), id
, adv_router
,
837 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
838 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
839 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
841 prefix
= (struct ospf6_prefix
*) current
;
842 if (prefix
->prefix_length
== 0 ||
843 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
846 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
848 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
850 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
852 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
854 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
857 memset (&in6
, 0, sizeof (in6
));
858 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
859 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
860 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
861 vty_out (vty
, " Prefix: %s/%d%s",
862 buf
, prefix
->prefix_length
, VNL
);
869 ospf6_intra_prefix_lsa_originate_stub (struct thread
*thread
)
871 struct ospf6_area
*oa
;
873 char buffer
[OSPF6_MAX_LSASIZE
];
874 struct ospf6_lsa_header
*lsa_header
;
875 struct ospf6_lsa
*old
, *lsa
;
877 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
878 struct ospf6_interface
*oi
;
879 struct ospf6_neighbor
*on
;
880 struct ospf6_route
*route
;
881 struct ospf6_prefix
*op
;
882 struct listnode
*i
, *j
;
884 unsigned short prefix_num
= 0;
885 char buf
[PREFIX2STR_BUFFER
];
886 struct ospf6_route_table
*route_advertise
;
888 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
889 oa
->thread_intra_prefix_lsa
= NULL
;
891 /* find previous LSA */
892 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
893 htonl (0), oa
->ospf6
->router_id
, oa
->lsdb
);
895 if (! IS_AREA_ENABLED (oa
))
898 ospf6_lsa_purge (old
);
902 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
903 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
907 memset (buffer
, 0, sizeof (buffer
));
908 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
909 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
910 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
912 /* Fill Intra-Area-Prefix-LSA */
913 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_ROUTER
);
914 intra_prefix_lsa
->ref_id
= htonl (0);
915 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
917 route_advertise
= ospf6_route_table_create (0, 0);
919 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, i
, oi
))
921 if (oi
->state
== OSPF6_INTERFACE_DOWN
)
923 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
924 zlog_debug (" Interface %s is down, ignore", oi
->interface
->name
);
930 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
931 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
934 if (oi
->state
!= OSPF6_INTERFACE_LOOPBACK
&&
935 oi
->state
!= OSPF6_INTERFACE_POINTTOPOINT
&&
938 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
939 zlog_debug (" Interface %s is not stub, ignore",
940 oi
->interface
->name
);
944 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
945 zlog_debug (" Interface %s:", oi
->interface
->name
);
947 /* connected prefix to advertise */
948 for (route
= ospf6_route_head (oi
->route_connected
); route
;
949 route
= ospf6_route_best_next (route
))
951 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
953 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
954 zlog_debug (" include %s", buf
);
956 ospf6_route_add (ospf6_route_copy (route
), route_advertise
);
960 if (route_advertise
->count
== 0)
963 ospf6_lsa_purge (old
);
964 ospf6_route_table_delete (route_advertise
);
968 /* put prefixes to advertise */
970 op
= (struct ospf6_prefix
*)
971 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
972 for (route
= ospf6_route_head (route_advertise
); route
;
973 route
= ospf6_route_best_next (route
))
975 op
->prefix_length
= route
->prefix
.prefixlen
;
976 op
->prefix_options
= route
->path
.prefix_options
;
977 op
->prefix_metric
= htons (route
->path
.cost
);
978 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
979 OSPF6_PREFIX_SPACE (op
->prefix_length
));
980 op
= OSPF6_PREFIX_NEXT (op
);
984 ospf6_route_table_delete (route_advertise
);
988 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
989 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
993 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
995 /* Fill LSA Header */
997 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
998 lsa_header
->id
= htonl (0);
999 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
1000 lsa_header
->seqnum
=
1001 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1002 lsa_header
->adv_router
, oa
->lsdb
);
1003 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1006 ospf6_lsa_checksum (lsa_header
);
1009 lsa
= ospf6_lsa_create (lsa_header
);
1012 ospf6_lsa_originate_area (lsa
, oa
);
1019 ospf6_intra_prefix_lsa_originate_transit (struct thread
*thread
)
1021 struct ospf6_interface
*oi
;
1023 char buffer
[OSPF6_MAX_LSASIZE
];
1024 struct ospf6_lsa_header
*lsa_header
;
1025 struct ospf6_lsa
*old
, *lsa
;
1027 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1028 struct ospf6_neighbor
*on
;
1029 struct ospf6_route
*route
;
1030 struct ospf6_prefix
*op
;
1033 unsigned short prefix_num
= 0;
1034 struct ospf6_route_table
*route_advertise
;
1035 struct ospf6_link_lsa
*link_lsa
;
1036 char *start
, *end
, *current
;
1038 char buf
[PREFIX2STR_BUFFER
];
1040 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1041 oi
->thread_intra_prefix_lsa
= NULL
;
1045 /* find previous LSA */
1046 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
1047 htonl (oi
->interface
->ifindex
),
1048 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
1050 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
1053 ospf6_lsa_purge (old
);
1057 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1058 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1059 oi
->interface
->name
);
1061 /* prepare buffer */
1062 memset (buffer
, 0, sizeof (buffer
));
1063 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
1064 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1065 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
1067 /* Fill Intra-Area-Prefix-LSA */
1068 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_NETWORK
);
1069 intra_prefix_lsa
->ref_id
= htonl (oi
->interface
->ifindex
);
1070 intra_prefix_lsa
->ref_adv_router
= oi
->area
->ospf6
->router_id
;
1072 if (oi
->state
!= OSPF6_INTERFACE_DR
)
1074 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1075 zlog_debug (" Interface is not DR");
1077 ospf6_lsa_purge (old
);
1082 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
1083 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
1086 if (full_count
== 0)
1088 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1089 zlog_debug (" Interface is stub");
1091 ospf6_lsa_purge (old
);
1095 /* connected prefix to advertise */
1096 route_advertise
= ospf6_route_table_create (0, 0);
1098 type
= ntohs (OSPF6_LSTYPE_LINK
);
1099 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
1100 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1102 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1105 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1106 zlog_debug (" include prefix from %s", lsa
->name
);
1108 if (lsa
->header
->adv_router
!= oi
->area
->ospf6
->router_id
)
1110 on
= ospf6_neighbor_lookup (lsa
->header
->adv_router
, oi
);
1111 if (on
== NULL
|| on
->state
!= OSPF6_NEIGHBOR_FULL
)
1113 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1114 zlog_debug (" Neighbor not found or not Full, ignore");
1119 link_lsa
= (struct ospf6_link_lsa
*)
1120 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
1122 prefix_num
= (unsigned short) ntohl (link_lsa
->prefix_num
);
1123 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
1124 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
1125 for (current
= start
; current
< end
&& prefix_num
;
1126 current
+= OSPF6_PREFIX_SIZE (op
))
1128 op
= (struct ospf6_prefix
*) current
;
1129 if (op
->prefix_length
== 0 ||
1130 current
+ OSPF6_PREFIX_SIZE (op
) > end
)
1133 route
= ospf6_route_create ();
1135 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1136 route
->prefix
.family
= AF_INET6
;
1137 route
->prefix
.prefixlen
= op
->prefix_length
;
1138 memset (&route
->prefix
.u
.prefix6
, 0, sizeof (struct in6_addr
));
1139 memcpy (&route
->prefix
.u
.prefix6
, OSPF6_PREFIX_BODY (op
),
1140 OSPF6_PREFIX_SPACE (op
->prefix_length
));
1142 route
->path
.origin
.type
= lsa
->header
->type
;
1143 route
->path
.origin
.id
= lsa
->header
->id
;
1144 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1145 route
->path
.options
[0] = link_lsa
->options
[0];
1146 route
->path
.options
[1] = link_lsa
->options
[1];
1147 route
->path
.options
[2] = link_lsa
->options
[2];
1148 route
->path
.prefix_options
= op
->prefix_options
;
1149 route
->path
.area_id
= oi
->area
->area_id
;
1150 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1152 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1154 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1155 zlog_debug (" include %s", buf
);
1158 ospf6_route_add (route
, route_advertise
);
1161 if (current
!= end
&& IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1162 zlog_debug ("Trailing garbage in %s", lsa
->name
);
1165 op
= (struct ospf6_prefix
*)
1166 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
1169 for (route
= ospf6_route_head (route_advertise
); route
;
1170 route
= ospf6_route_best_next (route
))
1172 op
->prefix_length
= route
->prefix
.prefixlen
;
1173 op
->prefix_options
= route
->path
.prefix_options
;
1174 op
->prefix_metric
= htons (0);
1175 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
1176 OSPF6_PREFIX_SPACE (op
->prefix_length
));
1177 op
= OSPF6_PREFIX_NEXT (op
);
1181 ospf6_route_table_delete (route_advertise
);
1183 if (prefix_num
== 0)
1185 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1186 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
1190 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
1192 /* Fill LSA Header */
1193 lsa_header
->age
= 0;
1194 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1195 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
1196 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
1197 lsa_header
->seqnum
=
1198 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1199 lsa_header
->adv_router
, oi
->area
->lsdb
);
1200 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1203 ospf6_lsa_checksum (lsa_header
);
1206 lsa
= ospf6_lsa_create (lsa_header
);
1209 ospf6_lsa_originate_area (lsa
, oi
->area
);
1215 ospf6_intra_prefix_lsa_add (struct ospf6_lsa
*lsa
)
1217 struct ospf6_area
*oa
;
1218 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1219 struct prefix ls_prefix
;
1220 struct ospf6_route
*route
, *ls_entry
;
1222 struct ospf6_prefix
*op
;
1223 char *start
, *current
, *end
;
1224 char buf
[PREFIX2STR_BUFFER
];
1225 struct interface
*ifp
;
1226 int direct_connect
= 0;
1228 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1231 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1232 zlog_debug ("%s found", lsa
->name
);
1234 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1236 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1237 OSPF6_LSA_HEADER_END (lsa
->header
);
1238 if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_ROUTER
))
1239 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1240 htonl (0), &ls_prefix
);
1241 else if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_NETWORK
))
1242 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1243 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1246 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1247 zlog_debug ("Unknown reference LS-type: %#hx",
1248 ntohs (intra_prefix_lsa
->ref_type
));
1252 ls_entry
= ospf6_route_lookup (&ls_prefix
, oa
->spf_table
);
1253 if (ls_entry
== NULL
)
1255 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1257 ospf6_linkstate_prefix2str (&ls_prefix
, buf
, sizeof (buf
));
1258 zlog_debug ("LS entry does not exist: %s", buf
);
1263 if (intra_prefix_lsa
->ref_adv_router
== oa
->ospf6
->router_id
)
1265 /* the intra-prefix are directly connected */
1269 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1270 start
= (caddr_t
) intra_prefix_lsa
+
1271 sizeof (struct ospf6_intra_prefix_lsa
);
1272 end
= OSPF6_LSA_END (lsa
->header
);
1273 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1275 op
= (struct ospf6_prefix
*) current
;
1276 if (prefix_num
== 0)
1278 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1281 /* Appendix A.4.1.1 */
1282 if (CHECK_FLAG(op
->prefix_options
, OSPF6_PREFIX_OPTION_NU
))
1284 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1286 ospf6_linkstate_prefix2str ((struct prefix
*)OSPF6_PREFIX_BODY(op
),
1288 zlog_debug ("%s: Skipping Prefix %s has NU option set",
1294 route
= ospf6_route_create ();
1296 memset (&route
->prefix
, 0, sizeof (struct prefix
));
1297 route
->prefix
.family
= AF_INET6
;
1298 route
->prefix
.prefixlen
= op
->prefix_length
;
1299 ospf6_prefix_in6_addr (&route
->prefix
.u
.prefix6
, op
);
1301 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1302 route
->path
.origin
.type
= lsa
->header
->type
;
1303 route
->path
.origin
.id
= lsa
->header
->id
;
1304 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1305 route
->path
.prefix_options
= op
->prefix_options
;
1306 route
->path
.area_id
= oa
->area_id
;
1307 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1308 route
->path
.metric_type
= 1;
1309 route
->path
.cost
= ls_entry
->path
.cost
+
1310 ntohs (op
->prefix_metric
);
1314 ifp
= if_lookup_prefix(&route
->prefix
, VRF_DEFAULT
);
1316 ospf6_route_add_nexthop (route
, ifp
->ifindex
, NULL
);
1320 ospf6_route_copy_nexthops (route
, ls_entry
);
1323 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1325 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1326 zlog_debug (" add %s", buf
);
1329 ospf6_route_add (route
, oa
->route_table
);
1333 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1334 zlog_debug ("Trailing garbage ignored");
1338 ospf6_intra_prefix_lsa_remove (struct ospf6_lsa
*lsa
)
1340 struct ospf6_area
*oa
;
1341 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1342 struct prefix prefix
;
1343 struct ospf6_route
*route
, *nroute
;
1345 struct ospf6_prefix
*op
;
1346 char *start
, *current
, *end
;
1347 char buf
[PREFIX2STR_BUFFER
];
1349 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1350 zlog_debug ("%s disappearing", lsa
->name
);
1352 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1354 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1355 OSPF6_LSA_HEADER_END (lsa
->header
);
1357 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1358 start
= (caddr_t
) intra_prefix_lsa
+
1359 sizeof (struct ospf6_intra_prefix_lsa
);
1360 end
= OSPF6_LSA_END (lsa
->header
);
1361 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1363 op
= (struct ospf6_prefix
*) current
;
1364 if (prefix_num
== 0)
1366 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1370 memset (&prefix
, 0, sizeof (struct prefix
));
1371 prefix
.family
= AF_INET6
;
1372 prefix
.prefixlen
= op
->prefix_length
;
1373 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, op
);
1375 route
= ospf6_route_lookup (&prefix
, oa
->route_table
);
1379 for (ospf6_route_lock (route
);
1380 route
&& ospf6_route_is_prefix (&prefix
, route
);
1383 nroute
= ospf6_route_next (route
);
1384 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
1386 if (route
->path
.area_id
!= oa
->area_id
)
1388 if (route
->path
.type
!= OSPF6_PATH_TYPE_INTRA
)
1390 if (route
->path
.origin
.type
!= lsa
->header
->type
||
1391 route
->path
.origin
.id
!= lsa
->header
->id
||
1392 route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
1395 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1397 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1398 zlog_debug ("remove %s", buf
);
1400 ospf6_route_remove (route
, oa
->route_table
);
1403 ospf6_route_unlock (route
);
1406 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1407 zlog_debug ("Trailing garbage ignored");
1411 ospf6_intra_route_calculation (struct ospf6_area
*oa
)
1413 struct ospf6_route
*route
, *nroute
;
1415 struct ospf6_lsa
*lsa
;
1416 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1417 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1419 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1420 zlog_debug ("Re-examin intra-routes for area %s", oa
->name
);
1422 hook_add
= oa
->route_table
->hook_add
;
1423 hook_remove
= oa
->route_table
->hook_remove
;
1424 oa
->route_table
->hook_add
= NULL
;
1425 oa
->route_table
->hook_remove
= NULL
;
1427 for (route
= ospf6_route_head (oa
->route_table
); route
;
1428 route
= ospf6_route_next (route
))
1429 route
->flag
= OSPF6_ROUTE_REMOVE
;
1431 type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1432 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
1433 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1434 ospf6_intra_prefix_lsa_add (lsa
);
1436 oa
->route_table
->hook_add
= hook_add
;
1437 oa
->route_table
->hook_remove
= hook_remove
;
1439 for (route
= ospf6_route_head (oa
->route_table
); route
;
1442 nroute
= ospf6_route_next (route
);
1443 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
) &&
1444 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
))
1446 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
);
1447 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_ADD
);
1450 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
1451 ospf6_route_remove (route
, oa
->route_table
);
1452 else if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
) ||
1453 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_CHANGE
))
1456 (*hook_add
) (route
);
1460 /* Redo the summaries as things might have changed */
1461 ospf6_abr_originate_summary (route
);
1466 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1467 zlog_debug ("Re-examin intra-routes for area %s: Done", oa
->name
);
1471 ospf6_brouter_debug_print (struct ospf6_route
*brouter
)
1473 u_int32_t brouter_id
;
1474 char brouter_name
[16];
1476 char destination
[64];
1477 char installed
[16], changed
[16];
1478 struct timeval now
, res
;
1479 char id
[16], adv_router
[16];
1480 char capa
[16], options
[16];
1482 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1483 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1484 inet_ntop (AF_INET
, &brouter
->path
.area_id
, area_name
, sizeof (area_name
));
1485 ospf6_linkstate_prefix2str (&brouter
->prefix
, destination
,
1486 sizeof (destination
));
1489 timersub (&now
, &brouter
->installed
, &res
);
1490 timerstring (&res
, installed
, sizeof (installed
));
1493 timersub (&now
, &brouter
->changed
, &res
);
1494 timerstring (&res
, changed
, sizeof (changed
));
1496 inet_ntop (AF_INET
, &brouter
->path
.origin
.id
, id
, sizeof (id
));
1497 inet_ntop (AF_INET
, &brouter
->path
.origin
.adv_router
, adv_router
,
1498 sizeof (adv_router
));
1500 ospf6_options_printbuf (brouter
->path
.options
, options
, sizeof (options
));
1501 ospf6_capability_printbuf (brouter
->path
.router_bits
, capa
, sizeof (capa
));
1503 zlog_info ("Brouter: %s via area %s", brouter_name
, area_name
);
1504 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1505 (void *)brouter
->prev
, (void *)brouter
, (void *)brouter
->next
,
1506 (void *)brouter
->rnode
);
1507 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1508 brouter
->type
, destination
, installed
, changed
);
1509 zlog_info (" lock: %d flags: %s%s%s%s", brouter
->lock
,
1510 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_BEST
) ? "B" : "-"),
1511 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ? "A" : "-"),
1512 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) ? "R" : "-"),
1513 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
) ? "C" : "-"));
1514 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1515 OSPF6_PATH_TYPE_NAME (brouter
->path
.type
),
1516 ospf6_lstype_name (brouter
->path
.origin
.type
),
1518 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1519 options
, capa
, brouter
->path
.metric_type
,
1520 brouter
->path
.cost
, brouter
->path
.u
.cost_e2
);
1524 ospf6_intra_brouter_calculation (struct ospf6_area
*oa
)
1526 struct ospf6_route
*brouter
, *nbrouter
, *copy
;
1527 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1528 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1529 u_int32_t brouter_id
;
1530 char brouter_name
[16];
1532 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1533 zlog_info ("border-router calculation for area %s", oa
->name
);
1535 hook_add
= oa
->ospf6
->brouter_table
->hook_add
;
1536 hook_remove
= oa
->ospf6
->brouter_table
->hook_remove
;
1537 oa
->ospf6
->brouter_table
->hook_add
= NULL
;
1538 oa
->ospf6
->brouter_table
->hook_remove
= NULL
;
1540 /* withdraw the previous router entries for the area */
1541 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1542 brouter
= ospf6_route_next (brouter
))
1544 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1545 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1546 if (brouter
->path
.area_id
!= oa
->area_id
)
1548 SET_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1550 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1551 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1553 zlog_info ("%p: mark as removing: area %s brouter %s",
1554 (void *)brouter
, oa
->name
, brouter_name
);
1555 ospf6_brouter_debug_print (brouter
);
1559 for (brouter
= ospf6_route_head (oa
->spf_table
); brouter
;
1560 brouter
= ospf6_route_next (brouter
))
1562 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1563 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1565 if (brouter
->type
!= OSPF6_DEST_TYPE_LINKSTATE
)
1567 if (ospf6_linkstate_prefix_id (&brouter
->prefix
) != htonl (0))
1569 if (! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_E
) &&
1570 ! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
1573 if (! OSPF6_OPT_ISSET (brouter
->path
.options
, OSPF6_OPT_V6
) ||
1574 ! OSPF6_OPT_ISSET (brouter
->path
.options
, OSPF6_OPT_R
))
1577 copy
= ospf6_route_copy (brouter
);
1578 copy
->type
= OSPF6_DEST_TYPE_ROUTER
;
1579 copy
->path
.area_id
= oa
->area_id
;
1580 ospf6_route_add (copy
, oa
->ospf6
->brouter_table
);
1582 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1583 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1585 zlog_info ("%p: transfer: area %s brouter %s",
1586 (void *)brouter
, oa
->name
, brouter_name
);
1587 ospf6_brouter_debug_print (brouter
);
1591 oa
->ospf6
->brouter_table
->hook_add
= hook_add
;
1592 oa
->ospf6
->brouter_table
->hook_remove
= hook_remove
;
1594 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1597 nbrouter
= ospf6_route_next (brouter
);
1598 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1599 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1601 if (brouter
->path
.area_id
!= oa
->area_id
)
1604 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
1607 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) &&
1608 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
))
1610 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1611 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
);
1614 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
))
1616 if (IS_OSPF6_DEBUG_BROUTER
||
1617 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1618 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1619 zlog_info ("brouter %s disappears via area %s",
1620 brouter_name
, oa
->name
);
1621 ospf6_route_remove (brouter
, oa
->ospf6
->brouter_table
);
1623 else if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ||
1624 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
))
1626 if (IS_OSPF6_DEBUG_BROUTER
||
1627 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1628 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1629 zlog_info ("brouter %s appears via area %s",
1630 brouter_name
, oa
->name
);
1634 (*hook_add
) (brouter
);
1638 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1639 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1640 zlog_info ("brouter %s still exists via area %s",
1641 brouter_name
, oa
->name
);
1642 /* But re-originate summaries */
1643 ospf6_abr_originate_summary (brouter
);
1645 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
);
1646 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
);
1649 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1650 zlog_info ("border-router calculation for area %s: done", oa
->name
);
1653 struct ospf6_lsa_handler router_handler
=
1655 OSPF6_LSTYPE_ROUTER
,
1658 ospf6_router_lsa_show
,
1659 ospf6_router_lsa_get_nbr_id
1662 struct ospf6_lsa_handler network_handler
=
1664 OSPF6_LSTYPE_NETWORK
,
1667 ospf6_network_lsa_show
,
1668 ospf6_network_lsa_get_ar_id
1671 struct ospf6_lsa_handler link_handler
=
1676 ospf6_link_lsa_show
,
1677 ospf6_link_lsa_get_prefix_str
1680 struct ospf6_lsa_handler intra_prefix_handler
=
1682 OSPF6_LSTYPE_INTRA_PREFIX
,
1685 ospf6_intra_prefix_lsa_show
,
1686 ospf6_intra_prefix_lsa_get_prefix_str
1690 ospf6_intra_init (void)
1692 ospf6_install_lsa_handler (&router_handler
);
1693 ospf6_install_lsa_handler (&network_handler
);
1694 ospf6_install_lsa_handler (&link_handler
);
1695 ospf6_install_lsa_handler (&intra_prefix_handler
);
1698 DEFUN (debug_ospf6_brouter
,
1699 debug_ospf6_brouter_cmd
,
1700 "debug ospf6 border-routers",
1703 "Debug border router\n"
1706 OSPF6_DEBUG_BROUTER_ON ();
1710 DEFUN (no_debug_ospf6_brouter
,
1711 no_debug_ospf6_brouter_cmd
,
1712 "no debug ospf6 border-routers",
1716 "Debug border router\n"
1719 OSPF6_DEBUG_BROUTER_OFF ();
1723 DEFUN (debug_ospf6_brouter_router
,
1724 debug_ospf6_brouter_router_cmd
,
1725 "debug ospf6 border-routers router-id A.B.C.D",
1728 "Debug border router\n"
1729 "Debug specific border router\n"
1730 "Specify border-router's router-id\n"
1734 u_int32_t router_id
;
1735 inet_pton (AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1736 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id
);
1740 DEFUN (no_debug_ospf6_brouter_router
,
1741 no_debug_ospf6_brouter_router_cmd
,
1742 "no debug ospf6 border-routers router-id",
1746 "Debug border router\n"
1747 "Debug specific border router\n"
1750 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1754 DEFUN (debug_ospf6_brouter_area
,
1755 debug_ospf6_brouter_area_cmd
,
1756 "debug ospf6 border-routers area-id A.B.C.D",
1759 "Debug border router\n"
1760 "Debug border routers in specific Area\n"
1766 inet_pton (AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
);
1767 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id
);
1771 DEFUN (no_debug_ospf6_brouter_area
,
1772 no_debug_ospf6_brouter_area_cmd
,
1773 "no debug ospf6 border-routers area-id",
1777 "Debug border router\n"
1778 "Debug border routers in specific Area\n"
1781 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1786 config_write_ospf6_debug_brouter (struct vty
*vty
)
1789 if (IS_OSPF6_DEBUG_BROUTER
)
1790 vty_out (vty
, "debug ospf6 border-routers%s", VNL
);
1791 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER
)
1793 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_router_id
,
1795 vty_out (vty
, "debug ospf6 border-routers router-id %s%s", buf
, VNL
);
1797 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA
)
1799 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_area_id
,
1801 vty_out (vty
, "debug ospf6 border-routers area-id %s%s", buf
, VNL
);
1807 install_element_ospf6_debug_brouter (void)
1809 install_element (ENABLE_NODE
, &debug_ospf6_brouter_cmd
);
1810 install_element (ENABLE_NODE
, &debug_ospf6_brouter_router_cmd
);
1811 install_element (ENABLE_NODE
, &debug_ospf6_brouter_area_cmd
);
1812 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_cmd
);
1813 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1814 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_area_cmd
);
1815 install_element (CONFIG_NODE
, &debug_ospf6_brouter_cmd
);
1816 install_element (CONFIG_NODE
, &debug_ospf6_brouter_router_cmd
);
1817 install_element (CONFIG_NODE
, &debug_ospf6_brouter_area_cmd
);
1818 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_cmd
);
1819 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1820 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_area_cmd
);