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 #define MAX_LSA_PAYLOAD (1024 + 256)
56 /******************************/
57 /* RFC2740 3.4.3.1 Router-LSA */
58 /******************************/
60 static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa
*lsa
, char *buf
,
63 struct ospf6_router_lsa
*router_lsa
;
64 struct ospf6_router_lsdesc
*lsdesc
;
66 char buf1
[INET_ADDRSTRLEN
], buf2
[INET_ADDRSTRLEN
];
69 router_lsa
= (struct ospf6_router_lsa
70 *)((char *)lsa
->header
71 + 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
77 + pos
* (sizeof(struct
78 ospf6_router_lsdesc
)));
79 if ((char *)lsdesc
< end
) {
80 if (buf
&& (buflen
> INET_ADDRSTRLEN
* 2)) {
82 &lsdesc
->neighbor_interface_id
, buf1
,
84 inet_ntop(AF_INET
, &lsdesc
->neighbor_router_id
,
86 sprintf(buf
, "%s/%s", buf2
, buf1
);
95 static int ospf6_router_lsa_show(struct vty
*vty
, struct ospf6_lsa
*lsa
)
97 char *start
, *end
, *current
;
98 char buf
[32], name
[32], bits
[16], options
[32];
99 struct ospf6_router_lsa
*router_lsa
;
100 struct ospf6_router_lsdesc
*lsdesc
;
103 (struct ospf6_router_lsa
*)((char *)lsa
->header
104 + 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\n", bits
, options
);
110 start
= (char *)router_lsa
+ sizeof(struct ospf6_router_lsa
);
111 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
112 for (current
= start
;
113 current
+ sizeof(struct ospf6_router_lsdesc
) <= end
;
114 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)",
129 vty_out(vty
, " Type: %s Metric: %d\n", name
,
130 ntohs(lsdesc
->metric
));
131 vty_out(vty
, " Interface ID: %s\n",
132 inet_ntop(AF_INET
, &lsdesc
->interface_id
, buf
,
134 vty_out(vty
, " Neighbor Interface ID: %s\n",
135 inet_ntop(AF_INET
, &lsdesc
->neighbor_interface_id
, buf
,
137 vty_out(vty
, " Neighbor Router ID: %s\n",
138 inet_ntop(AF_INET
, &lsdesc
->neighbor_router_id
, buf
,
144 static void 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
)) {
156 SET_FLAG(router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
158 UNSET_FLAG(router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
161 UNSET_FLAG(router_lsa
->bits
, OSPF6_ROUTER_BIT_V
);
162 UNSET_FLAG(router_lsa
->bits
, OSPF6_ROUTER_BIT_W
);
165 int ospf6_router_is_stub_router(struct ospf6_lsa
*lsa
)
167 struct ospf6_router_lsa
*rtr_lsa
;
169 if (lsa
!= NULL
&& OSPF6_LSA_IS_TYPE(ROUTER
, lsa
)) {
170 rtr_lsa
= (struct ospf6_router_lsa
171 *)((caddr_t
)lsa
->header
172 + sizeof(struct ospf6_lsa_header
));
174 if (!OSPF6_OPT_ISSET(rtr_lsa
->options
, OSPF6_OPT_R
)) {
175 return (OSPF6_IS_STUB_ROUTER
);
176 } else if (!OSPF6_OPT_ISSET(rtr_lsa
->options
, OSPF6_OPT_V6
)) {
177 return (OSPF6_IS_STUB_ROUTER_V6
);
181 return (OSPF6_NOT_STUB_ROUTER
);
184 int ospf6_router_lsa_originate(struct thread
*thread
)
186 struct ospf6_area
*oa
;
188 char buffer
[OSPF6_MAX_LSASIZE
];
189 struct ospf6_lsa_header
*lsa_header
;
190 struct ospf6_lsa
*lsa
;
192 u_int32_t link_state_id
= 0;
193 struct listnode
*node
, *nnode
;
195 struct ospf6_interface
*oi
;
196 struct ospf6_neighbor
*on
, *drouter
= NULL
;
197 struct ospf6_router_lsa
*router_lsa
;
198 struct ospf6_router_lsdesc
*lsdesc
;
203 oa
= (struct ospf6_area
*)THREAD_ARG(thread
);
204 oa
->thread_router_lsa
= NULL
;
206 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
207 zlog_debug("Originate Router-LSA for Area %s", oa
->name
);
209 memset(buffer
, 0, sizeof(buffer
));
210 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
212 (struct ospf6_router_lsa
*)((caddr_t
)lsa_header
213 + sizeof(struct ospf6_lsa_header
));
215 ospf6_router_lsa_options_set(oa
, router_lsa
);
217 /* describe links for each interfaces */
218 lsdesc
= (struct ospf6_router_lsdesc
*)((caddr_t
)router_lsa
219 + sizeof(struct ospf6_router_lsa
));
221 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
222 /* Interfaces in state Down or Loopback are not described */
223 if (oi
->state
== OSPF6_INTERFACE_DOWN
224 || oi
->state
== OSPF6_INTERFACE_LOOPBACK
)
227 /* Nor are interfaces without any full adjacencies described */
229 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, j
, on
))
230 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
236 /* Multiple Router-LSA instance according to size limit setting
238 if ((oa
->router_lsa_size_limit
!= 0)
239 && ((size_t)((char *)lsdesc
- buffer
)
240 + sizeof(struct ospf6_router_lsdesc
)
241 > oa
->router_lsa_size_limit
)) {
243 == (caddr_t
)router_lsa
244 + sizeof(struct ospf6_router_lsa
)) {
245 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
247 "Size limit setting for Router-LSA too short");
251 /* Fill LSA Header */
253 lsa_header
->type
= htons(OSPF6_LSTYPE_ROUTER
);
254 lsa_header
->id
= htonl(link_state_id
);
255 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
257 ospf6_new_ls_seqnum(lsa_header
->type
,
259 lsa_header
->adv_router
, oa
->lsdb
);
261 htons((caddr_t
)lsdesc
- (caddr_t
)buffer
);
264 ospf6_lsa_checksum(lsa_header
);
267 lsa
= ospf6_lsa_create(lsa_header
);
270 ospf6_lsa_originate_area(lsa
, oa
);
272 /* Reset Buffer to fill next Router LSA */
273 memset(buffer
, 0, sizeof(buffer
));
274 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
276 (struct ospf6_router_lsa
*)((caddr_t
)lsa_header
277 + sizeof(struct ospf6_lsa_header
));
279 ospf6_router_lsa_options_set(oa
, router_lsa
);
281 /* describe links for each interfaces */
282 lsdesc
= (struct ospf6_router_lsdesc
*)
283 ((caddr_t
)router_lsa
+
284 sizeof(struct ospf6_router_lsa
));
289 /* Point-to-Point interfaces */
290 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
) {
291 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, j
, on
)) {
292 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
295 lsdesc
->type
= OSPF6_ROUTER_LSDESC_POINTTOPOINT
;
296 lsdesc
->metric
= htons(oi
->cost
);
297 lsdesc
->interface_id
=
298 htonl(oi
->interface
->ifindex
);
299 lsdesc
->neighbor_interface_id
=
301 lsdesc
->neighbor_router_id
= on
->router_id
;
307 /* Broadcast and NBMA interfaces */
308 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
) {
309 /* If this router is not DR,
310 and If this router not fully adjacent with DR,
311 this interface is not transit yet: ignore. */
312 if (oi
->state
!= OSPF6_INTERFACE_DR
) {
314 ospf6_neighbor_lookup(oi
->drouter
, oi
);
316 || drouter
->state
!= OSPF6_NEIGHBOR_FULL
)
320 lsdesc
->type
= OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
;
321 lsdesc
->metric
= htons(oi
->cost
);
322 lsdesc
->interface_id
= htonl(oi
->interface
->ifindex
);
323 if (oi
->state
!= OSPF6_INTERFACE_DR
) {
324 lsdesc
->neighbor_interface_id
=
325 htonl(drouter
->ifindex
);
326 lsdesc
->neighbor_router_id
= drouter
->router_id
;
328 lsdesc
->neighbor_interface_id
=
329 htonl(oi
->interface
->ifindex
);
330 lsdesc
->neighbor_router_id
=
331 oi
->area
->ospf6
->router_id
;
336 assert(0); /* Unknown interface type */
341 /* Point-to-Multipoint interfaces */
345 /* Fill LSA Header */
347 lsa_header
->type
= htons(OSPF6_LSTYPE_ROUTER
);
348 lsa_header
->id
= htonl(link_state_id
);
349 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
351 ospf6_new_ls_seqnum(lsa_header
->type
, lsa_header
->id
,
352 lsa_header
->adv_router
, oa
->lsdb
);
353 lsa_header
->length
= htons((caddr_t
)lsdesc
- (caddr_t
)buffer
);
356 ospf6_lsa_checksum(lsa_header
);
359 lsa
= ospf6_lsa_create(lsa_header
);
362 ospf6_lsa_originate_area(lsa
, oa
);
366 /* Do premature-aging of rest, undesired Router-LSAs */
367 type
= ntohs(OSPF6_LSTYPE_ROUTER
);
368 router
= oa
->ospf6
->router_id
;
370 for (ALL_LSDB_TYPED_ADVRTR(oa
->lsdb
, type
, router
, lsa
)) {
371 if (ntohl(lsa
->header
->id
) < link_state_id
)
373 ospf6_lsa_purge(lsa
);
378 * Waiting till the LSA is actually removed from the database to trigger
379 * SPF delays network convergence. Unlike IPv4, for an ABR, when all
380 * interfaces associated with an area are gone, triggering an SPF right
382 * helps convergence with inter-area routes.
384 if (count
&& !link_state_id
)
385 ospf6_spf_schedule(oa
->ospf6
,
386 OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED
);
391 /*******************************/
392 /* RFC2740 3.4.3.2 Network-LSA */
393 /*******************************/
395 static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa
*lsa
, char *buf
,
398 char *start
, *end
, *current
;
399 struct ospf6_network_lsa
*network_lsa
;
400 struct ospf6_network_lsdesc
*lsdesc
;
403 network_lsa
= (struct ospf6_network_lsa
404 *)((caddr_t
)lsa
->header
405 + sizeof(struct ospf6_lsa_header
));
407 start
= (char *)network_lsa
+ sizeof(struct ospf6_network_lsa
);
408 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
409 current
= start
+ pos
* (sizeof(struct ospf6_network_lsdesc
));
411 if ((current
+ sizeof(struct ospf6_network_lsdesc
)) <= end
) {
412 lsdesc
= (struct ospf6_network_lsdesc
*)current
;
414 inet_ntop(AF_INET
, &lsdesc
->router_id
, buf
,
423 static int ospf6_network_lsa_show(struct vty
*vty
, struct ospf6_lsa
*lsa
)
425 char *start
, *end
, *current
;
426 struct ospf6_network_lsa
*network_lsa
;
427 struct ospf6_network_lsdesc
*lsdesc
;
428 char buf
[128], options
[32];
431 (struct ospf6_network_lsa
*)((caddr_t
)lsa
->header
432 + sizeof(struct ospf6_lsa_header
));
434 ospf6_options_printbuf(network_lsa
->options
, options
, sizeof(options
));
435 vty_out(vty
, " Options: %s\n", options
);
437 start
= (char *)network_lsa
+ sizeof(struct ospf6_network_lsa
);
438 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
439 for (current
= start
;
440 current
+ sizeof(struct ospf6_network_lsdesc
) <= end
;
441 current
+= sizeof(struct ospf6_network_lsdesc
)) {
442 lsdesc
= (struct ospf6_network_lsdesc
*)current
;
443 inet_ntop(AF_INET
, &lsdesc
->router_id
, buf
, sizeof(buf
));
444 vty_out(vty
, " Attached Router: %s\n", buf
);
449 int ospf6_network_lsa_originate(struct thread
*thread
)
451 struct ospf6_interface
*oi
;
453 char buffer
[OSPF6_MAX_LSASIZE
];
454 struct ospf6_lsa_header
*lsa_header
;
457 struct ospf6_lsa
*old
, *lsa
;
458 struct ospf6_network_lsa
*network_lsa
;
459 struct ospf6_network_lsdesc
*lsdesc
;
460 struct ospf6_neighbor
*on
;
461 struct ospf6_link_lsa
*link_lsa
;
465 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
466 oi
->thread_network_lsa
= NULL
;
468 /* The interface must be enabled until here. A Network-LSA of a
469 disabled interface (but was once enabled) should be flushed
470 by ospf6_lsa_refresh (), and does not come here. */
473 old
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_NETWORK
),
474 htonl(oi
->interface
->ifindex
),
475 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
477 /* Do not originate Network-LSA if not DR */
478 if (oi
->state
!= OSPF6_INTERFACE_DR
) {
480 ospf6_lsa_purge(old
);
482 * Waiting till the LSA is actually removed from the
484 * trigger SPF delays network convergence.
488 OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED
);
493 if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK
))
494 zlog_debug("Originate Network-LSA for Interface %s",
495 oi
->interface
->name
);
497 /* If none of neighbor is adjacent to us */
500 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, i
, on
))
501 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
505 if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK
))
506 zlog_debug("Interface stub, ignore");
508 ospf6_lsa_purge(old
);
513 memset(buffer
, 0, sizeof(buffer
));
514 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
516 (struct ospf6_network_lsa
*)((caddr_t
)lsa_header
517 + sizeof(struct ospf6_lsa_header
));
519 /* Collect the interface's Link-LSAs to describe
520 network's optional capabilities */
521 type
= htons(OSPF6_LSTYPE_LINK
);
522 for (ALL_LSDB_TYPED(oi
->lsdb
, type
, lsa
)) {
523 link_lsa
= (struct ospf6_link_lsa
524 *)((caddr_t
)lsa
->header
525 + sizeof(struct ospf6_lsa_header
));
526 network_lsa
->options
[0] |= link_lsa
->options
[0];
527 network_lsa
->options
[1] |= link_lsa
->options
[1];
528 network_lsa
->options
[2] |= link_lsa
->options
[2];
531 lsdesc
= (struct ospf6_network_lsdesc
532 *)((caddr_t
)network_lsa
533 + sizeof(struct ospf6_network_lsa
));
535 /* set Link Description to the router itself */
536 lsdesc
->router_id
= oi
->area
->ospf6
->router_id
;
539 /* Walk through the neighbors */
540 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, i
, on
)) {
541 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
544 /* set this neighbor's Router-ID to LSA */
545 lsdesc
->router_id
= on
->router_id
;
549 /* Fill LSA Header */
551 lsa_header
->type
= htons(OSPF6_LSTYPE_NETWORK
);
552 lsa_header
->id
= htonl(oi
->interface
->ifindex
);
553 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
555 ospf6_new_ls_seqnum(lsa_header
->type
, lsa_header
->id
,
556 lsa_header
->adv_router
, oi
->area
->lsdb
);
557 lsa_header
->length
= htons((caddr_t
)lsdesc
- (caddr_t
)buffer
);
560 ospf6_lsa_checksum(lsa_header
);
563 lsa
= ospf6_lsa_create(lsa_header
);
566 ospf6_lsa_originate_area(lsa
, oi
->area
);
572 /****************************/
573 /* RFC2740 3.4.3.6 Link-LSA */
574 /****************************/
576 static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa
*lsa
, char *buf
,
579 char *start
, *end
, *current
;
580 struct ospf6_link_lsa
*link_lsa
;
582 struct ospf6_prefix
*prefix
;
583 int cnt
= 0, prefixnum
;
586 link_lsa
= (struct ospf6_link_lsa
587 *)((caddr_t
)lsa
->header
588 + sizeof(struct ospf6_lsa_header
));
591 inet_ntop(AF_INET6
, &link_lsa
->linklocal_addr
, buf
,
596 prefixnum
= ntohl(link_lsa
->prefix_num
);
600 start
= (char *)link_lsa
+ sizeof(struct ospf6_link_lsa
);
601 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
605 prefix
= (struct ospf6_prefix
*)current
;
606 if (prefix
->prefix_length
== 0
607 || current
+ OSPF6_PREFIX_SIZE(prefix
) > end
) {
613 start
+ pos
* OSPF6_PREFIX_SIZE(prefix
);
616 memset(&in6
, 0, sizeof(in6
));
617 memcpy(&in6
, OSPF6_PREFIX_BODY(prefix
),
619 prefix
->prefix_length
));
620 inet_ntop(AF_INET6
, &in6
, buf
, buflen
);
623 } while (current
<= end
);
628 static int ospf6_link_lsa_show(struct vty
*vty
, struct ospf6_lsa
*lsa
)
630 char *start
, *end
, *current
;
631 struct ospf6_link_lsa
*link_lsa
;
633 char buf
[128], options
[32];
634 struct ospf6_prefix
*prefix
;
635 const char *p
, *mc
, *la
, *nu
;
638 link_lsa
= (struct ospf6_link_lsa
*)((caddr_t
)lsa
->header
639 + sizeof(struct ospf6_lsa_header
));
641 ospf6_options_printbuf(link_lsa
->options
, options
, sizeof(options
));
642 inet_ntop(AF_INET6
, &link_lsa
->linklocal_addr
, buf
, sizeof(buf
));
643 prefixnum
= ntohl(link_lsa
->prefix_num
);
645 vty_out(vty
, " Priority: %d Options: %s\n", link_lsa
->priority
,
647 vty_out(vty
, " LinkLocal Address: %s\n", buf
);
648 vty_out(vty
, " Number of Prefix: %d\n", prefixnum
);
650 start
= (char *)link_lsa
+ sizeof(struct ospf6_link_lsa
);
651 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
652 for (current
= start
; current
< end
;
653 current
+= OSPF6_PREFIX_SIZE(prefix
)) {
654 prefix
= (struct ospf6_prefix
*)current
;
655 if (prefix
->prefix_length
== 0
656 || current
+ OSPF6_PREFIX_SIZE(prefix
) > end
)
659 p
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
)
662 mc
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
)
665 la
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
)
668 nu
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
)
671 vty_out(vty
, " Prefix Options: %s|%s|%s|%s\n", p
, mc
, la
,
674 memset(&in6
, 0, sizeof(in6
));
675 memcpy(&in6
, OSPF6_PREFIX_BODY(prefix
),
676 OSPF6_PREFIX_SPACE(prefix
->prefix_length
));
677 inet_ntop(AF_INET6
, &in6
, buf
, sizeof(buf
));
678 vty_out(vty
, " Prefix: %s/%d\n", buf
,
679 prefix
->prefix_length
);
685 int ospf6_link_lsa_originate(struct thread
*thread
)
687 struct ospf6_interface
*oi
;
689 char buffer
[OSPF6_MAX_LSASIZE
];
690 struct ospf6_lsa_header
*lsa_header
;
691 struct ospf6_lsa
*old
, *lsa
;
693 struct ospf6_link_lsa
*link_lsa
;
694 struct ospf6_route
*route
;
695 struct ospf6_prefix
*op
;
697 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
698 oi
->thread_link_lsa
= NULL
;
702 /* find previous LSA */
703 old
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_LINK
),
704 htonl(oi
->interface
->ifindex
),
705 oi
->area
->ospf6
->router_id
, oi
->lsdb
);
707 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
709 ospf6_lsa_purge(old
);
713 if (IS_OSPF6_DEBUG_ORIGINATE(LINK
))
714 zlog_debug("Originate Link-LSA for Interface %s",
715 oi
->interface
->name
);
717 /* can't make Link-LSA if linklocal address not set */
718 if (oi
->linklocal_addr
== NULL
) {
719 if (IS_OSPF6_DEBUG_ORIGINATE(LINK
))
721 "No Linklocal address on %s, defer originating",
722 oi
->interface
->name
);
724 ospf6_lsa_purge(old
);
729 memset(buffer
, 0, sizeof(buffer
));
730 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
731 link_lsa
= (struct ospf6_link_lsa
*)((caddr_t
)lsa_header
732 + sizeof(struct ospf6_lsa_header
));
735 link_lsa
->priority
= oi
->priority
;
736 memcpy(link_lsa
->options
, oi
->area
->options
, 3);
737 memcpy(&link_lsa
->linklocal_addr
, oi
->linklocal_addr
,
738 sizeof(struct in6_addr
));
739 link_lsa
->prefix_num
= htonl(oi
->route_connected
->count
);
741 op
= (struct ospf6_prefix
*)((caddr_t
)link_lsa
742 + sizeof(struct ospf6_link_lsa
));
744 /* connected prefix to advertise */
745 for (route
= ospf6_route_head(oi
->route_connected
); route
;
746 route
= ospf6_route_next(route
)) {
747 op
->prefix_length
= route
->prefix
.prefixlen
;
748 op
->prefix_options
= route
->path
.prefix_options
;
749 op
->prefix_metric
= htons(0);
750 memcpy(OSPF6_PREFIX_BODY(op
), &route
->prefix
.u
.prefix6
,
751 OSPF6_PREFIX_SPACE(op
->prefix_length
));
752 op
= OSPF6_PREFIX_NEXT(op
);
755 /* Fill LSA Header */
757 lsa_header
->type
= htons(OSPF6_LSTYPE_LINK
);
758 lsa_header
->id
= htonl(oi
->interface
->ifindex
);
759 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
761 ospf6_new_ls_seqnum(lsa_header
->type
, lsa_header
->id
,
762 lsa_header
->adv_router
, oi
->lsdb
);
763 lsa_header
->length
= htons((caddr_t
)op
- (caddr_t
)buffer
);
766 ospf6_lsa_checksum(lsa_header
);
769 lsa
= ospf6_lsa_create(lsa_header
);
772 ospf6_lsa_originate_interface(lsa
, oi
);
778 /*****************************************/
779 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
780 /*****************************************/
781 static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa
*lsa
,
782 char *buf
, int buflen
,
785 char *start
, *end
, *current
;
786 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
788 int prefixnum
, cnt
= 0;
789 struct ospf6_prefix
*prefix
;
793 (struct ospf6_intra_prefix_lsa
794 *)((caddr_t
)lsa
->header
795 + sizeof(struct ospf6_lsa_header
));
797 prefixnum
= ntohs(intra_prefix_lsa
->prefix_num
);
801 start
= (char *)intra_prefix_lsa
802 + sizeof(struct ospf6_intra_prefix_lsa
);
803 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
807 prefix
= (struct ospf6_prefix
*)current
;
808 if (prefix
->prefix_length
== 0
809 || current
+ OSPF6_PREFIX_SIZE(prefix
) > end
) {
815 start
+ pos
* OSPF6_PREFIX_SIZE(prefix
);
818 memset(&in6
, 0, sizeof(in6
));
819 memcpy(&in6
, OSPF6_PREFIX_BODY(prefix
),
821 prefix
->prefix_length
));
822 inet_ntop(AF_INET6
, &in6
, buf
, buflen
);
823 sprintf(&buf
[strlen(buf
)], "/%d",
824 prefix
->prefix_length
);
827 } while (current
<= end
);
832 static int ospf6_intra_prefix_lsa_show(struct vty
*vty
, struct ospf6_lsa
*lsa
)
834 char *start
, *end
, *current
;
835 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
838 struct ospf6_prefix
*prefix
;
839 char id
[16], adv_router
[16];
840 const char *p
, *mc
, *la
, *nu
;
843 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
844 *)((caddr_t
)lsa
->header
845 + sizeof(struct ospf6_lsa_header
));
847 prefixnum
= ntohs(intra_prefix_lsa
->prefix_num
);
849 vty_out(vty
, " Number of Prefix: %d\n", prefixnum
);
851 inet_ntop(AF_INET
, &intra_prefix_lsa
->ref_id
, id
, sizeof(id
));
852 inet_ntop(AF_INET
, &intra_prefix_lsa
->ref_adv_router
, adv_router
,
854 vty_out(vty
, " Reference: %s Id: %s Adv: %s\n",
855 ospf6_lstype_name(intra_prefix_lsa
->ref_type
), id
, adv_router
);
857 start
= (char *)intra_prefix_lsa
858 + sizeof(struct ospf6_intra_prefix_lsa
);
859 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
860 for (current
= start
; current
< end
;
861 current
+= OSPF6_PREFIX_SIZE(prefix
)) {
862 prefix
= (struct ospf6_prefix
*)current
;
863 if (prefix
->prefix_length
== 0
864 || current
+ OSPF6_PREFIX_SIZE(prefix
) > end
)
867 p
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
)
870 mc
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
)
873 la
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
)
876 nu
= (CHECK_FLAG(prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
)
879 vty_out(vty
, " Prefix Options: %s|%s|%s|%s\n", p
, mc
, la
,
882 memset(&in6
, 0, sizeof(in6
));
883 memcpy(&in6
, OSPF6_PREFIX_BODY(prefix
),
884 OSPF6_PREFIX_SPACE(prefix
->prefix_length
));
885 inet_ntop(AF_INET6
, &in6
, buf
, sizeof(buf
));
886 vty_out(vty
, " Prefix: %s/%d\n", buf
,
887 prefix
->prefix_length
);
893 int ospf6_intra_prefix_lsa_originate_stub(struct thread
*thread
)
895 struct ospf6_area
*oa
;
897 char buffer
[OSPF6_MAX_LSASIZE
];
898 struct ospf6_lsa_header
*lsa_header
;
899 struct ospf6_lsa
*old
, *lsa
, *old_next
= NULL
;
901 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
902 struct ospf6_interface
*oi
;
903 struct ospf6_neighbor
*on
;
904 struct ospf6_route
*route
;
905 struct ospf6_prefix
*op
;
906 struct listnode
*i
, *j
;
908 unsigned short prefix_num
= 0;
909 char buf
[PREFIX2STR_BUFFER
];
910 struct ospf6_route_table
*route_advertise
;
913 oa
= (struct ospf6_area
*)THREAD_ARG(thread
);
914 oa
->thread_intra_prefix_lsa
= NULL
;
916 /* find previous LSA */
917 old
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_INTRA_PREFIX
), htonl(0),
918 oa
->ospf6
->router_id
, oa
->lsdb
);
920 if (!IS_AREA_ENABLED(oa
)) {
922 ospf6_lsa_purge(old
);
923 /* find previous LSA */
924 old_next
= ospf6_lsdb_lookup(
925 htons(OSPF6_LSTYPE_INTRA_PREFIX
),
927 oa
->ospf6
->router_id
, oa
->lsdb
);
930 ospf6_lsa_purge(old_next
);
931 old_next
= ospf6_lsdb_lookup(
932 htons(OSPF6_LSTYPE_INTRA_PREFIX
),
934 oa
->ospf6
->router_id
, oa
->lsdb
);
940 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
942 "Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
946 memset(buffer
, 0, sizeof(buffer
));
947 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
948 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)((caddr_t
)lsa_header
949 + sizeof(struct ospf6_lsa_header
));
951 /* Fill Intra-Area-Prefix-LSA */
952 intra_prefix_lsa
->ref_type
= htons(OSPF6_LSTYPE_ROUTER
);
953 intra_prefix_lsa
->ref_id
= htonl(0);
954 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
956 route_advertise
= ospf6_route_table_create(0, 0);
958 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
)) {
959 if (oi
->state
== OSPF6_INTERFACE_DOWN
) {
960 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
961 zlog_debug(" Interface %s is down, ignore",
962 oi
->interface
->name
);
968 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, j
, on
))
969 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
972 if (oi
->state
!= OSPF6_INTERFACE_LOOPBACK
973 && oi
->state
!= OSPF6_INTERFACE_POINTTOPOINT
974 && full_count
!= 0) {
975 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
976 zlog_debug(" Interface %s is not stub, ignore",
977 oi
->interface
->name
);
981 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
982 zlog_debug(" Interface %s:", oi
->interface
->name
);
984 /* connected prefix to advertise */
985 for (route
= ospf6_route_head(oi
->route_connected
); route
;
986 route
= ospf6_route_best_next(route
)) {
987 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
)) {
988 prefix2str(&route
->prefix
, buf
, sizeof(buf
));
989 zlog_debug(" include %s", buf
);
991 ospf6_route_add(ospf6_route_copy(route
),
996 if (route_advertise
->count
== 0) {
999 ospf6_lsa_purge(old
);
1000 /* find previous LSA */
1001 old_next
= ospf6_lsdb_lookup(
1002 htons(OSPF6_LSTYPE_INTRA_PREFIX
),
1004 oa
->ospf6
->router_id
, oa
->lsdb
);
1007 ospf6_lsa_purge(old_next
);
1008 old_next
= ospf6_lsdb_lookup(
1009 htons(OSPF6_LSTYPE_INTRA_PREFIX
),
1011 oa
->ospf6
->router_id
, oa
->lsdb
);
1014 ospf6_route_table_delete(route_advertise
);
1018 /* put prefixes to advertise */
1020 op
= (struct ospf6_prefix
*)((caddr_t
)intra_prefix_lsa
1021 + sizeof(struct ospf6_intra_prefix_lsa
));
1022 for (route
= ospf6_route_head(route_advertise
); route
;
1023 route
= ospf6_route_best_next(route
)) {
1024 if (((caddr_t
)op
- (caddr_t
)lsa_header
) > MAX_LSA_PAYLOAD
) {
1026 intra_prefix_lsa
->prefix_num
= htons(prefix_num
);
1028 /* Fill LSA Header */
1029 lsa_header
->age
= 0;
1030 lsa_header
->type
= htons(OSPF6_LSTYPE_INTRA_PREFIX
);
1031 lsa_header
->id
= htonl(ls_id
++);
1032 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
1033 lsa_header
->seqnum
=
1034 ospf6_new_ls_seqnum(lsa_header
->type
,
1036 lsa_header
->adv_router
,
1038 lsa_header
->length
= htons((caddr_t
)op
-
1039 (caddr_t
)lsa_header
);
1042 ospf6_lsa_checksum(lsa_header
);
1045 lsa
= ospf6_lsa_create(lsa_header
);
1048 ospf6_lsa_originate_area(lsa
, oa
);
1050 /* Prepare next buffer */
1051 memset(buffer
, 0, sizeof(buffer
));
1052 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
1053 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1054 ((caddr_t
)lsa_header
1055 + sizeof(struct ospf6_lsa_header
));
1057 /* Fill Intra-Area-Prefix-LSA */
1058 intra_prefix_lsa
->ref_type
= htons(OSPF6_LSTYPE_ROUTER
);
1059 intra_prefix_lsa
->ref_id
= htonl(0);
1060 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
1062 /* Put next set of prefixes to advertise */
1064 op
= (struct ospf6_prefix
*)((caddr_t
)intra_prefix_lsa
1065 + sizeof(struct ospf6_intra_prefix_lsa
));
1068 op
->prefix_length
= route
->prefix
.prefixlen
;
1069 op
->prefix_options
= route
->path
.prefix_options
;
1070 op
->prefix_metric
= htons(route
->path
.cost
);
1071 memcpy(OSPF6_PREFIX_BODY(op
), &route
->prefix
.u
.prefix6
,
1072 OSPF6_PREFIX_SPACE(op
->prefix_length
));
1075 op
= OSPF6_PREFIX_NEXT(op
);
1078 ospf6_route_table_delete(route_advertise
);
1080 if (prefix_num
== 0) {
1081 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1083 "Quit to Advertise Intra-Prefix: no route to advertise");
1087 intra_prefix_lsa
->prefix_num
= htons(prefix_num
);
1089 /* Fill LSA Header */
1090 lsa_header
->age
= 0;
1091 lsa_header
->type
= htons(OSPF6_LSTYPE_INTRA_PREFIX
);
1092 lsa_header
->id
= htonl(ls_id
++);
1093 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
1094 lsa_header
->seqnum
=
1095 ospf6_new_ls_seqnum(lsa_header
->type
, lsa_header
->id
,
1096 lsa_header
->adv_router
, oa
->lsdb
);
1097 lsa_header
->length
= htons((caddr_t
)op
- (caddr_t
)lsa_header
);
1100 ospf6_lsa_checksum(lsa_header
);
1103 lsa
= ospf6_lsa_create(lsa_header
);
1106 ospf6_lsa_originate_area(lsa
, oa
);
1112 int ospf6_intra_prefix_lsa_originate_transit(struct thread
*thread
)
1114 struct ospf6_interface
*oi
;
1116 char buffer
[OSPF6_MAX_LSASIZE
];
1117 struct ospf6_lsa_header
*lsa_header
;
1118 struct ospf6_lsa
*old
, *lsa
;
1120 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1121 struct ospf6_neighbor
*on
;
1122 struct ospf6_route
*route
;
1123 struct ospf6_prefix
*op
;
1126 unsigned short prefix_num
= 0;
1127 struct ospf6_route_table
*route_advertise
;
1128 struct ospf6_link_lsa
*link_lsa
;
1129 char *start
, *end
, *current
;
1131 char buf
[PREFIX2STR_BUFFER
];
1133 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
1134 oi
->thread_intra_prefix_lsa
= NULL
;
1138 /* find previous LSA */
1139 old
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_INTRA_PREFIX
),
1140 htonl(oi
->interface
->ifindex
),
1141 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
1143 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1145 ospf6_lsa_purge(old
);
1149 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1151 "Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1152 oi
->interface
->name
);
1154 /* prepare buffer */
1155 memset(buffer
, 0, sizeof(buffer
));
1156 lsa_header
= (struct ospf6_lsa_header
*)buffer
;
1157 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
1158 *)((caddr_t
)lsa_header
1159 + sizeof(struct ospf6_lsa_header
));
1161 /* Fill Intra-Area-Prefix-LSA */
1162 intra_prefix_lsa
->ref_type
= htons(OSPF6_LSTYPE_NETWORK
);
1163 intra_prefix_lsa
->ref_id
= htonl(oi
->interface
->ifindex
);
1164 intra_prefix_lsa
->ref_adv_router
= oi
->area
->ospf6
->router_id
;
1166 if (oi
->state
!= OSPF6_INTERFACE_DR
) {
1167 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1168 zlog_debug(" Interface is not DR");
1170 ospf6_lsa_purge(old
);
1175 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, i
, on
))
1176 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
1179 if (full_count
== 0) {
1180 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1181 zlog_debug(" Interface is stub");
1183 ospf6_lsa_purge(old
);
1187 /* connected prefix to advertise */
1188 route_advertise
= ospf6_route_table_create(0, 0);
1190 type
= ntohs(OSPF6_LSTYPE_LINK
);
1191 for (ALL_LSDB_TYPED(oi
->lsdb
, type
, lsa
)) {
1192 if (OSPF6_LSA_IS_MAXAGE(lsa
))
1195 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1196 zlog_debug(" include prefix from %s", lsa
->name
);
1198 if (lsa
->header
->adv_router
!= oi
->area
->ospf6
->router_id
) {
1199 on
= ospf6_neighbor_lookup(lsa
->header
->adv_router
, oi
);
1200 if (on
== NULL
|| on
->state
!= OSPF6_NEIGHBOR_FULL
) {
1201 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1203 " Neighbor not found or not Full, ignore");
1208 link_lsa
= (struct ospf6_link_lsa
1209 *)((caddr_t
)lsa
->header
1210 + sizeof(struct ospf6_lsa_header
));
1212 prefix_num
= (unsigned short)ntohl(link_lsa
->prefix_num
);
1213 start
= (char *)link_lsa
+ sizeof(struct ospf6_link_lsa
);
1214 end
= (char *)lsa
->header
+ ntohs(lsa
->header
->length
);
1215 for (current
= start
; current
< end
&& prefix_num
;
1216 current
+= OSPF6_PREFIX_SIZE(op
)) {
1217 op
= (struct ospf6_prefix
*)current
;
1218 if (op
->prefix_length
== 0
1219 || current
+ OSPF6_PREFIX_SIZE(op
) > end
)
1222 route
= ospf6_route_create();
1224 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1225 route
->prefix
.family
= AF_INET6
;
1226 route
->prefix
.prefixlen
= op
->prefix_length
;
1227 memset(&route
->prefix
.u
.prefix6
, 0,
1228 sizeof(struct in6_addr
));
1229 memcpy(&route
->prefix
.u
.prefix6
, OSPF6_PREFIX_BODY(op
),
1230 OSPF6_PREFIX_SPACE(op
->prefix_length
));
1232 route
->path
.origin
.type
= lsa
->header
->type
;
1233 route
->path
.origin
.id
= lsa
->header
->id
;
1234 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1235 route
->path
.options
[0] = link_lsa
->options
[0];
1236 route
->path
.options
[1] = link_lsa
->options
[1];
1237 route
->path
.options
[2] = link_lsa
->options
[2];
1238 route
->path
.prefix_options
= op
->prefix_options
;
1239 route
->path
.area_id
= oi
->area
->area_id
;
1240 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1242 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
)) {
1243 prefix2str(&route
->prefix
, buf
, sizeof(buf
));
1244 zlog_debug(" include %s", buf
);
1247 ospf6_route_add(route
, route_advertise
);
1250 if (current
!= end
&& IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1251 zlog_debug("Trailing garbage in %s", lsa
->name
);
1254 op
= (struct ospf6_prefix
*)((caddr_t
)intra_prefix_lsa
1255 + sizeof(struct ospf6_intra_prefix_lsa
));
1258 for (route
= ospf6_route_head(route_advertise
); route
;
1259 route
= ospf6_route_best_next(route
)) {
1260 op
->prefix_length
= route
->prefix
.prefixlen
;
1261 op
->prefix_options
= route
->path
.prefix_options
;
1262 op
->prefix_metric
= htons(0);
1263 memcpy(OSPF6_PREFIX_BODY(op
), &route
->prefix
.u
.prefix6
,
1264 OSPF6_PREFIX_SPACE(op
->prefix_length
));
1265 op
= OSPF6_PREFIX_NEXT(op
);
1269 ospf6_route_table_delete(route_advertise
);
1271 if (prefix_num
== 0) {
1272 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX
))
1274 "Quit to Advertise Intra-Prefix: no route to advertise");
1278 intra_prefix_lsa
->prefix_num
= htons(prefix_num
);
1280 /* Fill LSA Header */
1281 lsa_header
->age
= 0;
1282 lsa_header
->type
= htons(OSPF6_LSTYPE_INTRA_PREFIX
);
1283 lsa_header
->id
= htonl(oi
->interface
->ifindex
);
1284 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
1285 lsa_header
->seqnum
=
1286 ospf6_new_ls_seqnum(lsa_header
->type
, lsa_header
->id
,
1287 lsa_header
->adv_router
, oi
->area
->lsdb
);
1288 lsa_header
->length
= htons((caddr_t
)op
- (caddr_t
)lsa_header
);
1291 ospf6_lsa_checksum(lsa_header
);
1294 lsa
= ospf6_lsa_create(lsa_header
);
1297 ospf6_lsa_originate_area(lsa
, oi
->area
);
1302 void ospf6_intra_prefix_lsa_add(struct ospf6_lsa
*lsa
)
1304 struct ospf6_area
*oa
;
1305 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1306 struct prefix ls_prefix
;
1307 struct ospf6_route
*route
, *ls_entry
;
1309 struct ospf6_prefix
*op
;
1310 char *start
, *current
, *end
;
1311 char buf
[PREFIX2STR_BUFFER
];
1312 struct interface
*ifp
;
1313 int direct_connect
= 0;
1315 if (OSPF6_LSA_IS_MAXAGE(lsa
))
1318 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1319 zlog_debug("%s: LSA %s found", __PRETTY_FUNCTION__
, lsa
->name
);
1321 oa
= OSPF6_AREA(lsa
->lsdb
->data
);
1324 (struct ospf6_intra_prefix_lsa
*)OSPF6_LSA_HEADER_END(
1326 if (intra_prefix_lsa
->ref_type
== htons(OSPF6_LSTYPE_ROUTER
))
1327 ospf6_linkstate_prefix(intra_prefix_lsa
->ref_adv_router
,
1328 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1329 else if (intra_prefix_lsa
->ref_type
== htons(OSPF6_LSTYPE_NETWORK
))
1330 ospf6_linkstate_prefix(intra_prefix_lsa
->ref_adv_router
,
1331 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1333 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1334 zlog_debug("Unknown reference LS-type: %#hx",
1335 ntohs(intra_prefix_lsa
->ref_type
));
1339 ls_entry
= ospf6_route_lookup(&ls_prefix
, oa
->spf_table
);
1340 if (ls_entry
== NULL
) {
1341 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
)) {
1342 ospf6_linkstate_prefix2str(&ls_prefix
, buf
,
1344 zlog_debug("LS entry does not exist: %s", buf
);
1349 if (intra_prefix_lsa
->ref_adv_router
== oa
->ospf6
->router_id
) {
1350 /* the intra-prefix are directly connected */
1354 prefix_num
= ntohs(intra_prefix_lsa
->prefix_num
);
1355 start
= (caddr_t
)intra_prefix_lsa
1356 + sizeof(struct ospf6_intra_prefix_lsa
);
1357 end
= OSPF6_LSA_END(lsa
->header
);
1358 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE(op
)) {
1359 op
= (struct ospf6_prefix
*)current
;
1360 if (prefix_num
== 0)
1362 if (end
< current
+ OSPF6_PREFIX_SIZE(op
))
1365 /* Appendix A.4.1.1 */
1366 if (CHECK_FLAG(op
->prefix_options
, OSPF6_PREFIX_OPTION_NU
)) {
1367 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
)) {
1368 ospf6_linkstate_prefix2str(
1369 (struct prefix
*)OSPF6_PREFIX_BODY(op
),
1372 "%s: Skipping Prefix %s has NU option set",
1378 route
= ospf6_route_create();
1380 memset(&route
->prefix
, 0, sizeof(struct prefix
));
1381 route
->prefix
.family
= AF_INET6
;
1382 route
->prefix
.prefixlen
= op
->prefix_length
;
1383 ospf6_prefix_in6_addr(&route
->prefix
.u
.prefix6
, op
);
1385 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1386 route
->path
.origin
.type
= lsa
->header
->type
;
1387 route
->path
.origin
.id
= lsa
->header
->id
;
1388 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1389 route
->path
.prefix_options
= op
->prefix_options
;
1390 route
->path
.area_id
= oa
->area_id
;
1391 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1392 route
->path
.metric_type
= 1;
1394 ls_entry
->path
.cost
+ ntohs(op
->prefix_metric
);
1396 if (direct_connect
) {
1397 ifp
= if_lookup_prefix(&route
->prefix
, VRF_DEFAULT
);
1399 ospf6_route_add_nexthop(route
, ifp
->ifindex
,
1402 ospf6_route_copy_nexthops(route
, ls_entry
);
1405 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
)) {
1406 prefix2str(&route
->prefix
, buf
, sizeof(buf
));
1407 zlog_debug(" route %s add with nh count %u", buf
,
1408 listcount(route
->nh_list
));
1411 ospf6_route_add(route
, oa
->route_table
);
1415 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1416 zlog_debug("Trailing garbage ignored");
1419 void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa
*lsa
)
1421 struct ospf6_area
*oa
;
1422 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1423 struct prefix prefix
;
1424 struct ospf6_route
*route
, *nroute
;
1426 struct ospf6_prefix
*op
;
1427 char *start
, *current
, *end
;
1428 char buf
[PREFIX2STR_BUFFER
];
1430 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1431 zlog_debug("%s disappearing", lsa
->name
);
1433 oa
= OSPF6_AREA(lsa
->lsdb
->data
);
1436 (struct ospf6_intra_prefix_lsa
*)OSPF6_LSA_HEADER_END(
1439 prefix_num
= ntohs(intra_prefix_lsa
->prefix_num
);
1440 start
= (caddr_t
)intra_prefix_lsa
1441 + sizeof(struct ospf6_intra_prefix_lsa
);
1442 end
= OSPF6_LSA_END(lsa
->header
);
1443 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE(op
)) {
1444 op
= (struct ospf6_prefix
*)current
;
1445 if (prefix_num
== 0)
1447 if (end
< current
+ OSPF6_PREFIX_SIZE(op
))
1451 memset(&prefix
, 0, sizeof(struct prefix
));
1452 prefix
.family
= AF_INET6
;
1453 prefix
.prefixlen
= op
->prefix_length
;
1454 ospf6_prefix_in6_addr(&prefix
.u
.prefix6
, op
);
1456 route
= ospf6_route_lookup(&prefix
, oa
->route_table
);
1460 for (ospf6_route_lock(route
);
1461 route
&& ospf6_route_is_prefix(&prefix
, route
);
1463 nroute
= ospf6_route_next(route
);
1464 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
1466 if (route
->path
.area_id
!= oa
->area_id
)
1468 if (route
->path
.type
!= OSPF6_PATH_TYPE_INTRA
)
1470 if (route
->path
.origin
.type
!= lsa
->header
->type
1471 || route
->path
.origin
.id
!= lsa
->header
->id
1472 || route
->path
.origin
.adv_router
1473 != lsa
->header
->adv_router
)
1476 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
)) {
1477 prefix2str(&route
->prefix
, buf
, sizeof(buf
));
1478 zlog_debug("remove %s", buf
);
1480 ospf6_route_remove(route
, oa
->route_table
);
1483 ospf6_route_unlock(route
);
1486 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1487 zlog_debug("Trailing garbage ignored");
1490 void ospf6_intra_route_calculation(struct ospf6_area
*oa
)
1492 struct ospf6_route
*route
, *nroute
;
1494 struct ospf6_lsa
*lsa
;
1495 void (*hook_add
)(struct ospf6_route
*) = NULL
;
1496 void (*hook_remove
)(struct ospf6_route
*) = NULL
;
1498 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1499 zlog_debug("Re-examin intra-routes for area %s", oa
->name
);
1501 hook_add
= oa
->route_table
->hook_add
;
1502 hook_remove
= oa
->route_table
->hook_remove
;
1503 oa
->route_table
->hook_add
= NULL
;
1504 oa
->route_table
->hook_remove
= NULL
;
1506 for (route
= ospf6_route_head(oa
->route_table
); route
;
1507 route
= ospf6_route_next(route
))
1508 route
->flag
= OSPF6_ROUTE_REMOVE
;
1510 type
= htons(OSPF6_LSTYPE_INTRA_PREFIX
);
1511 for (ALL_LSDB_TYPED(oa
->lsdb
, type
, lsa
))
1512 ospf6_intra_prefix_lsa_add(lsa
);
1514 oa
->route_table
->hook_add
= hook_add
;
1515 oa
->route_table
->hook_remove
= hook_remove
;
1517 for (route
= ospf6_route_head(oa
->route_table
); route
; route
= nroute
) {
1518 nroute
= ospf6_route_next(route
);
1519 if (CHECK_FLAG(route
->flag
, OSPF6_ROUTE_REMOVE
)
1520 && CHECK_FLAG(route
->flag
, OSPF6_ROUTE_ADD
)) {
1521 UNSET_FLAG(route
->flag
, OSPF6_ROUTE_REMOVE
);
1522 UNSET_FLAG(route
->flag
, OSPF6_ROUTE_ADD
);
1525 if (CHECK_FLAG(route
->flag
, OSPF6_ROUTE_REMOVE
))
1526 ospf6_route_remove(route
, oa
->route_table
);
1527 else if (CHECK_FLAG(route
->flag
, OSPF6_ROUTE_ADD
)
1528 || CHECK_FLAG(route
->flag
, OSPF6_ROUTE_CHANGE
)) {
1533 /* Redo the summaries as things might have changed */
1534 ospf6_abr_originate_summary(route
);
1539 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX
))
1540 zlog_debug("Re-examin intra-routes for area %s: Done",
1544 static void ospf6_brouter_debug_print(struct ospf6_route
*brouter
)
1546 u_int32_t brouter_id
;
1547 char brouter_name
[16];
1549 char destination
[64];
1550 char installed
[64], changed
[64];
1551 struct timeval now
, res
;
1552 char id
[16], adv_router
[16];
1553 char capa
[16], options
[16];
1555 brouter_id
= ADV_ROUTER_IN_PREFIX(&brouter
->prefix
);
1556 inet_ntop(AF_INET
, &brouter_id
, brouter_name
, sizeof(brouter_name
));
1557 inet_ntop(AF_INET
, &brouter
->path
.area_id
, area_name
,
1559 ospf6_linkstate_prefix2str(&brouter
->prefix
, destination
,
1560 sizeof(destination
));
1563 timersub(&now
, &brouter
->installed
, &res
);
1564 timerstring(&res
, installed
, sizeof(installed
));
1567 timersub(&now
, &brouter
->changed
, &res
);
1568 timerstring(&res
, changed
, sizeof(changed
));
1570 inet_ntop(AF_INET
, &brouter
->path
.origin
.id
, id
, sizeof(id
));
1571 inet_ntop(AF_INET
, &brouter
->path
.origin
.adv_router
, adv_router
,
1572 sizeof(adv_router
));
1574 ospf6_options_printbuf(brouter
->path
.options
, options
, sizeof(options
));
1575 ospf6_capability_printbuf(brouter
->path
.router_bits
, capa
,
1578 zlog_info("Brouter: %s via area %s", brouter_name
, area_name
);
1579 zlog_info(" memory: prev: %p this: %p next: %p parent rnode: %p",
1580 (void *)brouter
->prev
, (void *)brouter
, (void *)brouter
->next
,
1581 (void *)brouter
->rnode
);
1582 zlog_info(" type: %d prefix: %s installed: %s changed: %s",
1583 brouter
->type
, destination
, installed
, changed
);
1584 zlog_info(" lock: %d flags: %s%s%s%s", brouter
->lock
,
1585 (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_BEST
) ? "B" : "-"),
1586 (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_ADD
) ? "A" : "-"),
1587 (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_REMOVE
) ? "R" : "-"),
1588 (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_CHANGE
) ? "C" : "-"));
1589 zlog_info(" path type: %s ls-origin %s id: %s adv-router %s",
1590 OSPF6_PATH_TYPE_NAME(brouter
->path
.type
),
1591 ospf6_lstype_name(brouter
->path
.origin
.type
), id
, adv_router
);
1592 zlog_info(" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1593 options
, capa
, brouter
->path
.metric_type
, brouter
->path
.cost
,
1594 brouter
->path
.u
.cost_e2
);
1597 void ospf6_intra_brouter_calculation(struct ospf6_area
*oa
)
1599 struct ospf6_route
*brouter
, *nbrouter
, *copy
;
1600 void (*hook_add
)(struct ospf6_route
*) = NULL
;
1601 void (*hook_remove
)(struct ospf6_route
*) = NULL
;
1602 u_int32_t brouter_id
;
1603 char brouter_name
[16];
1605 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa
->area_id
))
1606 zlog_info("border-router calculation for area %s", oa
->name
);
1608 hook_add
= oa
->ospf6
->brouter_table
->hook_add
;
1609 hook_remove
= oa
->ospf6
->brouter_table
->hook_remove
;
1610 oa
->ospf6
->brouter_table
->hook_add
= NULL
;
1611 oa
->ospf6
->brouter_table
->hook_remove
= NULL
;
1613 /* withdraw the previous router entries for the area */
1614 for (brouter
= ospf6_route_head(oa
->ospf6
->brouter_table
); brouter
;
1615 brouter
= ospf6_route_next(brouter
)) {
1616 brouter_id
= ADV_ROUTER_IN_PREFIX(&brouter
->prefix
);
1617 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
1618 sizeof(brouter_name
));
1619 if (brouter
->path
.area_id
!= oa
->area_id
)
1621 SET_FLAG(brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1623 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id
)
1624 || IS_OSPF6_DEBUG_ROUTE(MEMORY
)) {
1625 zlog_info("%p: mark as removing: area %s brouter %s",
1626 (void *)brouter
, oa
->name
, brouter_name
);
1627 ospf6_brouter_debug_print(brouter
);
1631 for (brouter
= ospf6_route_head(oa
->spf_table
); brouter
;
1632 brouter
= ospf6_route_next(brouter
)) {
1633 brouter_id
= ADV_ROUTER_IN_PREFIX(&brouter
->prefix
);
1634 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
1635 sizeof(brouter_name
));
1637 if (brouter
->type
!= OSPF6_DEST_TYPE_LINKSTATE
)
1639 if (ospf6_linkstate_prefix_id(&brouter
->prefix
) != htonl(0))
1641 if (!CHECK_FLAG(brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_E
)
1642 && !CHECK_FLAG(brouter
->path
.router_bits
,
1643 OSPF6_ROUTER_BIT_B
))
1646 if (!OSPF6_OPT_ISSET(brouter
->path
.options
, OSPF6_OPT_V6
)
1647 || !OSPF6_OPT_ISSET(brouter
->path
.options
, OSPF6_OPT_R
))
1650 copy
= ospf6_route_copy(brouter
);
1651 copy
->type
= OSPF6_DEST_TYPE_ROUTER
;
1652 copy
->path
.area_id
= oa
->area_id
;
1653 ospf6_route_add(copy
, oa
->ospf6
->brouter_table
);
1655 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id
)
1656 || IS_OSPF6_DEBUG_ROUTE(MEMORY
)) {
1657 zlog_info("%p: transfer: area %s brouter %s",
1658 (void *)brouter
, oa
->name
, brouter_name
);
1659 ospf6_brouter_debug_print(brouter
);
1663 oa
->ospf6
->brouter_table
->hook_add
= hook_add
;
1664 oa
->ospf6
->brouter_table
->hook_remove
= hook_remove
;
1666 for (brouter
= ospf6_route_head(oa
->ospf6
->brouter_table
); brouter
;
1667 brouter
= nbrouter
) {
1669 * brouter may have been "deleted" in the last loop iteration.
1670 * If this is the case there is still 1 final refcount lock
1671 * taken by ospf6_route_next, that will be released by the same
1672 * call and result in deletion. To avoid heap UAF we must then
1673 * skip processing the deleted route.
1675 if (brouter
->lock
== 1) {
1676 nbrouter
= ospf6_route_next(brouter
);
1679 nbrouter
= ospf6_route_next(brouter
);
1682 brouter_id
= ADV_ROUTER_IN_PREFIX(&brouter
->prefix
);
1683 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
1684 sizeof(brouter_name
));
1686 if (brouter
->path
.area_id
!= oa
->area_id
)
1689 if (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
1692 if (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_REMOVE
)
1693 && CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_ADD
)) {
1694 UNSET_FLAG(brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1695 UNSET_FLAG(brouter
->flag
, OSPF6_ROUTE_ADD
);
1698 if (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_REMOVE
)) {
1699 if (IS_OSPF6_DEBUG_BROUTER
1700 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1702 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1704 zlog_info("brouter %s disappears via area %s",
1705 brouter_name
, oa
->name
);
1706 ospf6_route_remove(brouter
, oa
->ospf6
->brouter_table
);
1708 } else if (CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_ADD
)
1709 || CHECK_FLAG(brouter
->flag
, OSPF6_ROUTE_CHANGE
)) {
1710 if (IS_OSPF6_DEBUG_BROUTER
1711 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1713 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1715 zlog_info("brouter %s appears via area %s",
1716 brouter_name
, oa
->name
);
1720 (*hook_add
)(brouter
);
1722 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1724 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1726 zlog_info("brouter %s still exists via area %s",
1727 brouter_name
, oa
->name
);
1728 /* But re-originate summaries */
1729 ospf6_abr_originate_summary(brouter
);
1733 UNSET_FLAG(brouter
->flag
, OSPF6_ROUTE_ADD
);
1734 UNSET_FLAG(brouter
->flag
, OSPF6_ROUTE_CHANGE
);
1738 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa
->area_id
))
1739 zlog_info("border-router calculation for area %s: done",
1743 struct ospf6_lsa_handler router_handler
= {
1744 .lh_type
= OSPF6_LSTYPE_ROUTER
,
1745 .lh_name
= "Router",
1746 .lh_short_name
= "Rtr",
1747 .lh_show
= ospf6_router_lsa_show
,
1748 .lh_get_prefix_str
= ospf6_router_lsa_get_nbr_id
,
1752 struct ospf6_lsa_handler network_handler
= {
1753 .lh_type
= OSPF6_LSTYPE_NETWORK
,
1754 .lh_name
= "Network",
1755 .lh_short_name
= "Net",
1756 .lh_show
= ospf6_network_lsa_show
,
1757 .lh_get_prefix_str
= ospf6_network_lsa_get_ar_id
,
1761 struct ospf6_lsa_handler link_handler
= {
1762 .lh_type
= OSPF6_LSTYPE_LINK
,
1764 .lh_short_name
= "Lnk",
1765 .lh_show
= ospf6_link_lsa_show
,
1766 .lh_get_prefix_str
= ospf6_link_lsa_get_prefix_str
,
1770 struct ospf6_lsa_handler intra_prefix_handler
= {
1771 .lh_type
= OSPF6_LSTYPE_INTRA_PREFIX
,
1772 .lh_name
= "Intra-Prefix",
1773 .lh_short_name
= "INP",
1774 .lh_show
= ospf6_intra_prefix_lsa_show
,
1775 .lh_get_prefix_str
= ospf6_intra_prefix_lsa_get_prefix_str
,
1779 void ospf6_intra_init(void)
1781 ospf6_install_lsa_handler(&router_handler
);
1782 ospf6_install_lsa_handler(&network_handler
);
1783 ospf6_install_lsa_handler(&link_handler
);
1784 ospf6_install_lsa_handler(&intra_prefix_handler
);
1787 DEFUN (debug_ospf6_brouter
,
1788 debug_ospf6_brouter_cmd
,
1789 "debug ospf6 border-routers",
1792 "Debug border router\n"
1795 OSPF6_DEBUG_BROUTER_ON();
1799 DEFUN (no_debug_ospf6_brouter
,
1800 no_debug_ospf6_brouter_cmd
,
1801 "no debug ospf6 border-routers",
1805 "Debug border router\n"
1808 OSPF6_DEBUG_BROUTER_OFF();
1812 DEFUN (debug_ospf6_brouter_router
,
1813 debug_ospf6_brouter_router_cmd
,
1814 "debug ospf6 border-routers router-id A.B.C.D",
1817 "Debug border router\n"
1818 "Debug specific border router\n"
1819 "Specify border-router's router-id\n"
1823 u_int32_t router_id
;
1824 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1825 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON(router_id
);
1829 DEFUN (no_debug_ospf6_brouter_router
,
1830 no_debug_ospf6_brouter_router_cmd
,
1831 "no debug ospf6 border-routers router-id",
1835 "Debug border router\n"
1836 "Debug specific border router\n"
1839 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF();
1843 DEFUN (debug_ospf6_brouter_area
,
1844 debug_ospf6_brouter_area_cmd
,
1845 "debug ospf6 border-routers area-id A.B.C.D",
1848 "Debug border router\n"
1849 "Debug border routers in specific Area\n"
1855 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
);
1856 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON(area_id
);
1860 DEFUN (no_debug_ospf6_brouter_area
,
1861 no_debug_ospf6_brouter_area_cmd
,
1862 "no debug ospf6 border-routers area-id",
1866 "Debug border router\n"
1867 "Debug border routers in specific Area\n"
1870 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF();
1874 int config_write_ospf6_debug_brouter(struct vty
*vty
)
1877 if (IS_OSPF6_DEBUG_BROUTER
)
1878 vty_out(vty
, "debug ospf6 border-routers\n");
1879 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER
) {
1880 inet_ntop(AF_INET
, &conf_debug_ospf6_brouter_specific_router_id
,
1882 vty_out(vty
, "debug ospf6 border-routers router-id %s\n", buf
);
1884 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA
) {
1885 inet_ntop(AF_INET
, &conf_debug_ospf6_brouter_specific_area_id
,
1887 vty_out(vty
, "debug ospf6 border-routers area-id %s\n", buf
);
1892 void install_element_ospf6_debug_brouter(void)
1894 install_element(ENABLE_NODE
, &debug_ospf6_brouter_cmd
);
1895 install_element(ENABLE_NODE
, &debug_ospf6_brouter_router_cmd
);
1896 install_element(ENABLE_NODE
, &debug_ospf6_brouter_area_cmd
);
1897 install_element(ENABLE_NODE
, &no_debug_ospf6_brouter_cmd
);
1898 install_element(ENABLE_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1899 install_element(ENABLE_NODE
, &no_debug_ospf6_brouter_area_cmd
);
1900 install_element(CONFIG_NODE
, &debug_ospf6_brouter_cmd
);
1901 install_element(CONFIG_NODE
, &debug_ospf6_brouter_router_cmd
);
1902 install_element(CONFIG_NODE
, &debug_ospf6_brouter_area_cmd
);
1903 install_element(CONFIG_NODE
, &no_debug_ospf6_brouter_cmd
);
1904 install_element(CONFIG_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1905 install_element(CONFIG_NODE
, &no_debug_ospf6_brouter_area_cmd
);