]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_intra.c
Merge pull request #828 from tigranmartirosyan/master
[mirror_frr.git] / ospf6d / ospf6_intra.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "linklist.h"
25 #include "thread.h"
26 #include "memory.h"
27 #include "if.h"
28 #include "prefix.h"
29 #include "table.h"
30 #include "vty.h"
31 #include "command.h"
32 #include "vrf.h"
33
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"
39
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"
48 #include "ospf6d.h"
49 #include "ospf6_spf.h"
50
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;
54
55 /******************************/
56 /* RFC2740 3.4.3.1 Router-LSA */
57 /******************************/
58
59 static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf,
60 int buflen, int pos)
61 {
62 struct ospf6_router_lsa *router_lsa;
63 struct ospf6_router_lsdesc *lsdesc;
64 char *start, *end;
65 char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
66
67 if (lsa) {
68 router_lsa = (struct ospf6_router_lsa
69 *)((char *)lsa->header
70 + sizeof(struct ospf6_lsa_header));
71 start = (char *)router_lsa + sizeof(struct ospf6_router_lsa);
72 end = (char *)lsa->header + ntohs(lsa->header->length);
73
74 lsdesc = (struct ospf6_router_lsdesc
75 *)(start
76 + pos
77 * (sizeof(struct
78 ospf6_router_lsdesc)));
79 if ((char *)lsdesc < end) {
80 if (buf && (buflen > INET_ADDRSTRLEN * 2)) {
81 inet_ntop(AF_INET,
82 &lsdesc->neighbor_interface_id, buf1,
83 sizeof(buf1));
84 inet_ntop(AF_INET, &lsdesc->neighbor_router_id,
85 buf2, sizeof(buf2));
86 sprintf(buf, "%s/%s", buf2, buf1);
87 }
88 } else
89 return NULL;
90 }
91
92 return buf;
93 }
94
95 static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
96 {
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;
101
102 router_lsa =
103 (struct ospf6_router_lsa *)((char *)lsa->header
104 + sizeof(struct ospf6_lsa_header));
105
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);
109
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;
116
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");
125 else
126 snprintf(name, sizeof(name), "Unknown (%#x)",
127 lsdesc->type);
128
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,
133 sizeof(buf)));
134 vty_out(vty, " Neighbor Interface ID: %s\n",
135 inet_ntop(AF_INET, &lsdesc->neighbor_interface_id, buf,
136 sizeof(buf)));
137 vty_out(vty, " Neighbor Router ID: %s\n",
138 inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf,
139 sizeof(buf)));
140 }
141 return 0;
142 }
143
144 static void ospf6_router_lsa_options_set(struct ospf6_area *oa,
145 struct ospf6_router_lsa *router_lsa)
146 {
147 OSPF6_OPT_CLEAR_ALL(router_lsa->options);
148 memcpy(router_lsa->options, oa->options, 3);
149
150 if (ospf6_is_router_abr(ospf6))
151 SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B);
152 else
153 UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B);
154
155 if (!IS_AREA_STUB(oa) && ospf6_asbr_is_asbr(oa->ospf6)) {
156 SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_E);
157 } else {
158 UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_E);
159 }
160
161 UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_V);
162 UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_W);
163 }
164
165 int ospf6_router_is_stub_router(struct ospf6_lsa *lsa)
166 {
167 struct ospf6_router_lsa *rtr_lsa;
168
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));
173
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);
178 }
179 }
180
181 return (OSPF6_NOT_STUB_ROUTER);
182 }
183
184 int ospf6_router_lsa_originate(struct thread *thread)
185 {
186 struct ospf6_area *oa;
187
188 char buffer[OSPF6_MAX_LSASIZE];
189 struct ospf6_lsa_header *lsa_header;
190 struct ospf6_lsa *lsa;
191
192 u_int32_t link_state_id = 0;
193 struct listnode *node, *nnode;
194 struct listnode *j;
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;
199 u_int16_t type;
200 u_int32_t router;
201 int count;
202
203 oa = (struct ospf6_area *)THREAD_ARG(thread);
204 oa->thread_router_lsa = NULL;
205
206 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER))
207 zlog_debug("Originate Router-LSA for Area %s", oa->name);
208
209 memset(buffer, 0, sizeof(buffer));
210 lsa_header = (struct ospf6_lsa_header *)buffer;
211 router_lsa =
212 (struct ospf6_router_lsa *)((caddr_t)lsa_header
213 + sizeof(struct ospf6_lsa_header));
214
215 ospf6_router_lsa_options_set(oa, router_lsa);
216
217 /* describe links for each interfaces */
218 lsdesc = (struct ospf6_router_lsdesc
219 *)((caddr_t)router_lsa
220 + sizeof(struct ospf6_router_lsa));
221
222 for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
223 /* Interfaces in state Down or Loopback are not described */
224 if (oi->state == OSPF6_INTERFACE_DOWN
225 || oi->state == OSPF6_INTERFACE_LOOPBACK)
226 continue;
227
228 /* Nor are interfaces without any full adjacencies described */
229 count = 0;
230 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on))
231 if (on->state == OSPF6_NEIGHBOR_FULL)
232 count++;
233
234 if (count == 0)
235 continue;
236
237 /* Multiple Router-LSA instance according to size limit setting
238 */
239 if ((oa->router_lsa_size_limit != 0)
240 && ((size_t)((char *)lsdesc - buffer)
241 + sizeof(struct ospf6_router_lsdesc)
242 > oa->router_lsa_size_limit)) {
243 if ((caddr_t)lsdesc
244 == (caddr_t)router_lsa
245 + sizeof(struct ospf6_router_lsa)) {
246 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER))
247 zlog_debug(
248 "Size limit setting for Router-LSA too short");
249 return 0;
250 }
251
252 link_state_id++;
253 }
254
255 /* Point-to-Point interfaces */
256 if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
257 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) {
258 if (on->state != OSPF6_NEIGHBOR_FULL)
259 continue;
260
261 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
262 lsdesc->metric = htons(oi->cost);
263 lsdesc->interface_id =
264 htonl(oi->interface->ifindex);
265 lsdesc->neighbor_interface_id =
266 htonl(on->ifindex);
267 lsdesc->neighbor_router_id = on->router_id;
268
269 lsdesc++;
270 }
271 }
272
273 /* Broadcast and NBMA interfaces */
274 else if (oi->type == OSPF_IFTYPE_BROADCAST) {
275 /* If this router is not DR,
276 and If this router not fully adjacent with DR,
277 this interface is not transit yet: ignore. */
278 if (oi->state != OSPF6_INTERFACE_DR) {
279 drouter =
280 ospf6_neighbor_lookup(oi->drouter, oi);
281 if (drouter == NULL
282 || drouter->state != OSPF6_NEIGHBOR_FULL)
283 continue;
284 }
285
286 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
287 lsdesc->metric = htons(oi->cost);
288 lsdesc->interface_id = htonl(oi->interface->ifindex);
289 if (oi->state != OSPF6_INTERFACE_DR) {
290 lsdesc->neighbor_interface_id =
291 htonl(drouter->ifindex);
292 lsdesc->neighbor_router_id = drouter->router_id;
293 } else {
294 lsdesc->neighbor_interface_id =
295 htonl(oi->interface->ifindex);
296 lsdesc->neighbor_router_id =
297 oi->area->ospf6->router_id;
298 }
299
300 lsdesc++;
301 } else {
302 assert(0); /* Unknown interface type */
303 }
304
305 /* Virtual links */
306 /* xxx */
307 /* Point-to-Multipoint interfaces */
308 /* xxx */
309 }
310
311 /* Fill LSA Header */
312 lsa_header->age = 0;
313 lsa_header->type = htons(OSPF6_LSTYPE_ROUTER);
314 lsa_header->id = htonl(link_state_id);
315 lsa_header->adv_router = oa->ospf6->router_id;
316 lsa_header->seqnum =
317 ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
318 lsa_header->adv_router, oa->lsdb);
319 lsa_header->length = htons((caddr_t)lsdesc - (caddr_t)buffer);
320
321 /* LSA checksum */
322 ospf6_lsa_checksum(lsa_header);
323
324 /* create LSA */
325 lsa = ospf6_lsa_create(lsa_header);
326
327 /* Originate */
328 ospf6_lsa_originate_area(lsa, oa);
329
330 link_state_id++;
331
332 /* Do premature-aging of rest, undesired Router-LSAs */
333 type = ntohs(OSPF6_LSTYPE_ROUTER);
334 router = oa->ospf6->router_id;
335 count = 0;
336 for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router, lsa)) {
337 if (ntohl(lsa->header->id) < link_state_id)
338 continue;
339 ospf6_lsa_purge(lsa);
340 count++;
341 }
342
343 /*
344 * Waiting till the LSA is actually removed from the database to trigger
345 * SPF delays network convergence. Unlike IPv4, for an ABR, when all
346 * interfaces associated with an area are gone, triggering an SPF right
347 * away
348 * helps convergence with inter-area routes.
349 */
350 if (count && !link_state_id)
351 ospf6_spf_schedule(oa->ospf6,
352 OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED);
353
354 return 0;
355 }
356
357 /*******************************/
358 /* RFC2740 3.4.3.2 Network-LSA */
359 /*******************************/
360
361 static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa *lsa, char *buf,
362 int buflen, int pos)
363 {
364 char *start, *end, *current;
365 struct ospf6_network_lsa *network_lsa;
366 struct ospf6_network_lsdesc *lsdesc;
367
368 if (lsa) {
369 network_lsa = (struct ospf6_network_lsa
370 *)((caddr_t)lsa->header
371 + sizeof(struct ospf6_lsa_header));
372
373 start = (char *)network_lsa + sizeof(struct ospf6_network_lsa);
374 end = (char *)lsa->header + ntohs(lsa->header->length);
375 current = start + pos * (sizeof(struct ospf6_network_lsdesc));
376
377 if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) {
378 lsdesc = (struct ospf6_network_lsdesc *)current;
379 if (buf)
380 inet_ntop(AF_INET, &lsdesc->router_id, buf,
381 buflen);
382 } else
383 return NULL;
384 }
385
386 return (buf);
387 }
388
389 static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
390 {
391 char *start, *end, *current;
392 struct ospf6_network_lsa *network_lsa;
393 struct ospf6_network_lsdesc *lsdesc;
394 char buf[128], options[32];
395
396 network_lsa =
397 (struct ospf6_network_lsa *)((caddr_t)lsa->header
398 + sizeof(struct ospf6_lsa_header));
399
400 ospf6_options_printbuf(network_lsa->options, options, sizeof(options));
401 vty_out(vty, " Options: %s\n", options);
402
403 start = (char *)network_lsa + sizeof(struct ospf6_network_lsa);
404 end = (char *)lsa->header + ntohs(lsa->header->length);
405 for (current = start;
406 current + sizeof(struct ospf6_network_lsdesc) <= end;
407 current += sizeof(struct ospf6_network_lsdesc)) {
408 lsdesc = (struct ospf6_network_lsdesc *)current;
409 inet_ntop(AF_INET, &lsdesc->router_id, buf, sizeof(buf));
410 vty_out(vty, " Attached Router: %s\n", buf);
411 }
412 return 0;
413 }
414
415 int ospf6_network_lsa_originate(struct thread *thread)
416 {
417 struct ospf6_interface *oi;
418
419 char buffer[OSPF6_MAX_LSASIZE];
420 struct ospf6_lsa_header *lsa_header;
421
422 int count;
423 struct ospf6_lsa *old, *lsa;
424 struct ospf6_network_lsa *network_lsa;
425 struct ospf6_network_lsdesc *lsdesc;
426 struct ospf6_neighbor *on;
427 struct ospf6_link_lsa *link_lsa;
428 struct listnode *i;
429 u_int16_t type;
430
431 oi = (struct ospf6_interface *)THREAD_ARG(thread);
432 oi->thread_network_lsa = NULL;
433
434 /* The interface must be enabled until here. A Network-LSA of a
435 disabled interface (but was once enabled) should be flushed
436 by ospf6_lsa_refresh (), and does not come here. */
437 assert(oi->area);
438
439 old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_NETWORK),
440 htonl(oi->interface->ifindex),
441 oi->area->ospf6->router_id, oi->area->lsdb);
442
443 /* Do not originate Network-LSA if not DR */
444 if (oi->state != OSPF6_INTERFACE_DR) {
445 if (old) {
446 ospf6_lsa_purge(old);
447 /*
448 * Waiting till the LSA is actually removed from the
449 * database to
450 * trigger SPF delays network convergence.
451 */
452 ospf6_spf_schedule(
453 oi->area->ospf6,
454 OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED);
455 }
456 return 0;
457 }
458
459 if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK))
460 zlog_debug("Originate Network-LSA for Interface %s",
461 oi->interface->name);
462
463 /* If none of neighbor is adjacent to us */
464 count = 0;
465
466 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on))
467 if (on->state == OSPF6_NEIGHBOR_FULL)
468 count++;
469
470 if (count == 0) {
471 if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK))
472 zlog_debug("Interface stub, ignore");
473 if (old)
474 ospf6_lsa_purge(old);
475 return 0;
476 }
477
478 /* prepare buffer */
479 memset(buffer, 0, sizeof(buffer));
480 lsa_header = (struct ospf6_lsa_header *)buffer;
481 network_lsa =
482 (struct ospf6_network_lsa *)((caddr_t)lsa_header
483 + sizeof(struct ospf6_lsa_header));
484
485 /* Collect the interface's Link-LSAs to describe
486 network's optional capabilities */
487 type = htons(OSPF6_LSTYPE_LINK);
488 for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) {
489 link_lsa = (struct ospf6_link_lsa
490 *)((caddr_t)lsa->header
491 + sizeof(struct ospf6_lsa_header));
492 network_lsa->options[0] |= link_lsa->options[0];
493 network_lsa->options[1] |= link_lsa->options[1];
494 network_lsa->options[2] |= link_lsa->options[2];
495 }
496
497 lsdesc = (struct ospf6_network_lsdesc
498 *)((caddr_t)network_lsa
499 + sizeof(struct ospf6_network_lsa));
500
501 /* set Link Description to the router itself */
502 lsdesc->router_id = oi->area->ospf6->router_id;
503 lsdesc++;
504
505 /* Walk through the neighbors */
506 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on)) {
507 if (on->state != OSPF6_NEIGHBOR_FULL)
508 continue;
509
510 /* set this neighbor's Router-ID to LSA */
511 lsdesc->router_id = on->router_id;
512 lsdesc++;
513 }
514
515 /* Fill LSA Header */
516 lsa_header->age = 0;
517 lsa_header->type = htons(OSPF6_LSTYPE_NETWORK);
518 lsa_header->id = htonl(oi->interface->ifindex);
519 lsa_header->adv_router = oi->area->ospf6->router_id;
520 lsa_header->seqnum =
521 ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
522 lsa_header->adv_router, oi->area->lsdb);
523 lsa_header->length = htons((caddr_t)lsdesc - (caddr_t)buffer);
524
525 /* LSA checksum */
526 ospf6_lsa_checksum(lsa_header);
527
528 /* create LSA */
529 lsa = ospf6_lsa_create(lsa_header);
530
531 /* Originate */
532 ospf6_lsa_originate_area(lsa, oi->area);
533
534 return 0;
535 }
536
537
538 /****************************/
539 /* RFC2740 3.4.3.6 Link-LSA */
540 /****************************/
541
542 static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
543 int buflen, int pos)
544 {
545 char *start, *end, *current;
546 struct ospf6_link_lsa *link_lsa;
547 struct in6_addr in6;
548 struct ospf6_prefix *prefix;
549 int cnt = 0, prefixnum;
550
551 if (lsa) {
552 link_lsa = (struct ospf6_link_lsa
553 *)((caddr_t)lsa->header
554 + sizeof(struct ospf6_lsa_header));
555
556 if (pos == 0) {
557 inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf,
558 buflen);
559 return (buf);
560 }
561
562 prefixnum = ntohl(link_lsa->prefix_num);
563 if (pos > prefixnum)
564 return (NULL);
565
566 start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
567 end = (char *)lsa->header + ntohs(lsa->header->length);
568 current = start;
569
570 do {
571 prefix = (struct ospf6_prefix *)current;
572 if (prefix->prefix_length == 0
573 || current + OSPF6_PREFIX_SIZE(prefix) > end) {
574 return (NULL);
575 }
576
577 if (cnt < pos) {
578 current =
579 start + pos * OSPF6_PREFIX_SIZE(prefix);
580 cnt++;
581 } else {
582 memset(&in6, 0, sizeof(in6));
583 memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
584 OSPF6_PREFIX_SPACE(
585 prefix->prefix_length));
586 inet_ntop(AF_INET6, &in6, buf, buflen);
587 return (buf);
588 }
589 } while (current <= end);
590 }
591 return (NULL);
592 }
593
594 static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
595 {
596 char *start, *end, *current;
597 struct ospf6_link_lsa *link_lsa;
598 int prefixnum;
599 char buf[128], options[32];
600 struct ospf6_prefix *prefix;
601 const char *p, *mc, *la, *nu;
602 struct in6_addr in6;
603
604 link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa->header
605 + sizeof(struct ospf6_lsa_header));
606
607 ospf6_options_printbuf(link_lsa->options, options, sizeof(options));
608 inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf));
609 prefixnum = ntohl(link_lsa->prefix_num);
610
611 vty_out(vty, " Priority: %d Options: %s\n", link_lsa->priority,
612 options);
613 vty_out(vty, " LinkLocal Address: %s\n", buf);
614 vty_out(vty, " Number of Prefix: %d\n", prefixnum);
615
616 start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
617 end = (char *)lsa->header + ntohs(lsa->header->length);
618 for (current = start; current < end;
619 current += OSPF6_PREFIX_SIZE(prefix)) {
620 prefix = (struct ospf6_prefix *)current;
621 if (prefix->prefix_length == 0
622 || current + OSPF6_PREFIX_SIZE(prefix) > end)
623 break;
624
625 p = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_P)
626 ? "P"
627 : "--");
628 mc = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_MC)
629 ? "MC"
630 : "--");
631 la = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_LA)
632 ? "LA"
633 : "--");
634 nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU)
635 ? "NU"
636 : "--");
637 vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la,
638 nu);
639
640 memset(&in6, 0, sizeof(in6));
641 memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
642 OSPF6_PREFIX_SPACE(prefix->prefix_length));
643 inet_ntop(AF_INET6, &in6, buf, sizeof(buf));
644 vty_out(vty, " Prefix: %s/%d\n", buf,
645 prefix->prefix_length);
646 }
647
648 return 0;
649 }
650
651 int ospf6_link_lsa_originate(struct thread *thread)
652 {
653 struct ospf6_interface *oi;
654
655 char buffer[OSPF6_MAX_LSASIZE];
656 struct ospf6_lsa_header *lsa_header;
657 struct ospf6_lsa *old, *lsa;
658
659 struct ospf6_link_lsa *link_lsa;
660 struct ospf6_route *route;
661 struct ospf6_prefix *op;
662
663 oi = (struct ospf6_interface *)THREAD_ARG(thread);
664 oi->thread_link_lsa = NULL;
665
666 assert(oi->area);
667
668 /* find previous LSA */
669 old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_LINK),
670 htonl(oi->interface->ifindex),
671 oi->area->ospf6->router_id, oi->lsdb);
672
673 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
674 if (old)
675 ospf6_lsa_purge(old);
676 return 0;
677 }
678
679 if (IS_OSPF6_DEBUG_ORIGINATE(LINK))
680 zlog_debug("Originate Link-LSA for Interface %s",
681 oi->interface->name);
682
683 /* can't make Link-LSA if linklocal address not set */
684 if (oi->linklocal_addr == NULL) {
685 if (IS_OSPF6_DEBUG_ORIGINATE(LINK))
686 zlog_debug(
687 "No Linklocal address on %s, defer originating",
688 oi->interface->name);
689 if (old)
690 ospf6_lsa_purge(old);
691 return 0;
692 }
693
694 /* prepare buffer */
695 memset(buffer, 0, sizeof(buffer));
696 lsa_header = (struct ospf6_lsa_header *)buffer;
697 link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa_header
698 + sizeof(struct ospf6_lsa_header));
699
700 /* Fill Link-LSA */
701 link_lsa->priority = oi->priority;
702 memcpy(link_lsa->options, oi->area->options, 3);
703 memcpy(&link_lsa->linklocal_addr, oi->linklocal_addr,
704 sizeof(struct in6_addr));
705 link_lsa->prefix_num = htonl(oi->route_connected->count);
706
707 op = (struct ospf6_prefix *)((caddr_t)link_lsa
708 + sizeof(struct ospf6_link_lsa));
709
710 /* connected prefix to advertise */
711 for (route = ospf6_route_head(oi->route_connected); route;
712 route = ospf6_route_next(route)) {
713 op->prefix_length = route->prefix.prefixlen;
714 op->prefix_options = route->path.prefix_options;
715 op->prefix_metric = htons(0);
716 memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6,
717 OSPF6_PREFIX_SPACE(op->prefix_length));
718 op = OSPF6_PREFIX_NEXT(op);
719 }
720
721 /* Fill LSA Header */
722 lsa_header->age = 0;
723 lsa_header->type = htons(OSPF6_LSTYPE_LINK);
724 lsa_header->id = htonl(oi->interface->ifindex);
725 lsa_header->adv_router = oi->area->ospf6->router_id;
726 lsa_header->seqnum =
727 ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
728 lsa_header->adv_router, oi->lsdb);
729 lsa_header->length = htons((caddr_t)op - (caddr_t)buffer);
730
731 /* LSA checksum */
732 ospf6_lsa_checksum(lsa_header);
733
734 /* create LSA */
735 lsa = ospf6_lsa_create(lsa_header);
736
737 /* Originate */
738 ospf6_lsa_originate_interface(lsa, oi);
739
740 return 0;
741 }
742
743
744 /*****************************************/
745 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
746 /*****************************************/
747 static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
748 char *buf, int buflen,
749 int pos)
750 {
751 char *start, *end, *current;
752 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
753 struct in6_addr in6;
754 int prefixnum, cnt = 0;
755 struct ospf6_prefix *prefix;
756
757 if (lsa) {
758 intra_prefix_lsa =
759 (struct ospf6_intra_prefix_lsa
760 *)((caddr_t)lsa->header
761 + sizeof(struct ospf6_lsa_header));
762
763 prefixnum = ntohs(intra_prefix_lsa->prefix_num);
764 if (pos > prefixnum)
765 return (NULL);
766
767 start = (char *)intra_prefix_lsa
768 + sizeof(struct ospf6_intra_prefix_lsa);
769 end = (char *)lsa->header + ntohs(lsa->header->length);
770 current = start;
771
772 do {
773 prefix = (struct ospf6_prefix *)current;
774 if (prefix->prefix_length == 0
775 || current + OSPF6_PREFIX_SIZE(prefix) > end) {
776 return NULL;
777 }
778
779 if (cnt < pos) {
780 current =
781 start + pos * OSPF6_PREFIX_SIZE(prefix);
782 cnt++;
783 } else {
784 memset(&in6, 0, sizeof(in6));
785 memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
786 OSPF6_PREFIX_SPACE(
787 prefix->prefix_length));
788 inet_ntop(AF_INET6, &in6, buf, buflen);
789 sprintf(&buf[strlen(buf)], "/%d",
790 prefix->prefix_length);
791 return (buf);
792 }
793 } while (current <= end);
794 }
795 return (buf);
796 }
797
798 static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
799 {
800 char *start, *end, *current;
801 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
802 int prefixnum;
803 char buf[128];
804 struct ospf6_prefix *prefix;
805 char id[16], adv_router[16];
806 const char *p, *mc, *la, *nu;
807 struct in6_addr in6;
808
809 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
810 *)((caddr_t)lsa->header
811 + sizeof(struct ospf6_lsa_header));
812
813 prefixnum = ntohs(intra_prefix_lsa->prefix_num);
814
815 vty_out(vty, " Number of Prefix: %d\n", prefixnum);
816
817 inet_ntop(AF_INET, &intra_prefix_lsa->ref_id, id, sizeof(id));
818 inet_ntop(AF_INET, &intra_prefix_lsa->ref_adv_router, adv_router,
819 sizeof(adv_router));
820 vty_out(vty, " Reference: %s Id: %s Adv: %s\n",
821 ospf6_lstype_name(intra_prefix_lsa->ref_type), id, adv_router);
822
823 start = (char *)intra_prefix_lsa
824 + sizeof(struct ospf6_intra_prefix_lsa);
825 end = (char *)lsa->header + ntohs(lsa->header->length);
826 for (current = start; current < end;
827 current += OSPF6_PREFIX_SIZE(prefix)) {
828 prefix = (struct ospf6_prefix *)current;
829 if (prefix->prefix_length == 0
830 || current + OSPF6_PREFIX_SIZE(prefix) > end)
831 break;
832
833 p = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_P)
834 ? "P"
835 : "--");
836 mc = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_MC)
837 ? "MC"
838 : "--");
839 la = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_LA)
840 ? "LA"
841 : "--");
842 nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU)
843 ? "NU"
844 : "--");
845 vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la,
846 nu);
847
848 memset(&in6, 0, sizeof(in6));
849 memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
850 OSPF6_PREFIX_SPACE(prefix->prefix_length));
851 inet_ntop(AF_INET6, &in6, buf, sizeof(buf));
852 vty_out(vty, " Prefix: %s/%d\n", buf,
853 prefix->prefix_length);
854 }
855
856 return 0;
857 }
858
859 int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
860 {
861 struct ospf6_area *oa;
862
863 char buffer[OSPF6_MAX_LSASIZE];
864 struct ospf6_lsa_header *lsa_header;
865 struct ospf6_lsa *old, *lsa;
866
867 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
868 struct ospf6_interface *oi;
869 struct ospf6_neighbor *on;
870 struct ospf6_route *route;
871 struct ospf6_prefix *op;
872 struct listnode *i, *j;
873 int full_count = 0;
874 unsigned short prefix_num = 0;
875 char buf[PREFIX2STR_BUFFER];
876 struct ospf6_route_table *route_advertise;
877
878 oa = (struct ospf6_area *)THREAD_ARG(thread);
879 oa->thread_intra_prefix_lsa = NULL;
880
881 /* find previous LSA */
882 old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_INTRA_PREFIX), htonl(0),
883 oa->ospf6->router_id, oa->lsdb);
884
885 if (!IS_AREA_ENABLED(oa)) {
886 if (old)
887 ospf6_lsa_purge(old);
888 return 0;
889 }
890
891 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
892 zlog_debug(
893 "Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
894 oa->name);
895
896 /* prepare buffer */
897 memset(buffer, 0, sizeof(buffer));
898 lsa_header = (struct ospf6_lsa_header *)buffer;
899 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
900 *)((caddr_t)lsa_header
901 + sizeof(struct ospf6_lsa_header));
902
903 /* Fill Intra-Area-Prefix-LSA */
904 intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER);
905 intra_prefix_lsa->ref_id = htonl(0);
906 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
907
908 route_advertise = ospf6_route_table_create(0, 0);
909
910 for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi)) {
911 if (oi->state == OSPF6_INTERFACE_DOWN) {
912 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
913 zlog_debug(" Interface %s is down, ignore",
914 oi->interface->name);
915 continue;
916 }
917
918 full_count = 0;
919
920 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on))
921 if (on->state == OSPF6_NEIGHBOR_FULL)
922 full_count++;
923
924 if (oi->state != OSPF6_INTERFACE_LOOPBACK
925 && oi->state != OSPF6_INTERFACE_POINTTOPOINT
926 && full_count != 0) {
927 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
928 zlog_debug(" Interface %s is not stub, ignore",
929 oi->interface->name);
930 continue;
931 }
932
933 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
934 zlog_debug(" Interface %s:", oi->interface->name);
935
936 /* connected prefix to advertise */
937 for (route = ospf6_route_head(oi->route_connected); route;
938 route = ospf6_route_best_next(route)) {
939 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) {
940 prefix2str(&route->prefix, buf, sizeof(buf));
941 zlog_debug(" include %s", buf);
942 }
943 ospf6_route_add(ospf6_route_copy(route),
944 route_advertise);
945 }
946 }
947
948 if (route_advertise->count == 0) {
949 if (old)
950 ospf6_lsa_purge(old);
951 ospf6_route_table_delete(route_advertise);
952 return 0;
953 }
954
955 /* put prefixes to advertise */
956 prefix_num = 0;
957 op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
958 + sizeof(struct ospf6_intra_prefix_lsa));
959 for (route = ospf6_route_head(route_advertise); route;
960 route = ospf6_route_best_next(route)) {
961 op->prefix_length = route->prefix.prefixlen;
962 op->prefix_options = route->path.prefix_options;
963 op->prefix_metric = htons(route->path.cost);
964 memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6,
965 OSPF6_PREFIX_SPACE(op->prefix_length));
966 op = OSPF6_PREFIX_NEXT(op);
967 prefix_num++;
968 }
969
970 ospf6_route_table_delete(route_advertise);
971
972 if (prefix_num == 0) {
973 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
974 zlog_debug(
975 "Quit to Advertise Intra-Prefix: no route to advertise");
976 return 0;
977 }
978
979 intra_prefix_lsa->prefix_num = htons(prefix_num);
980
981 /* Fill LSA Header */
982 lsa_header->age = 0;
983 lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
984 lsa_header->id = htonl(0);
985 lsa_header->adv_router = oa->ospf6->router_id;
986 lsa_header->seqnum =
987 ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
988 lsa_header->adv_router, oa->lsdb);
989 lsa_header->length = htons((caddr_t)op - (caddr_t)lsa_header);
990
991 /* LSA checksum */
992 ospf6_lsa_checksum(lsa_header);
993
994 /* create LSA */
995 lsa = ospf6_lsa_create(lsa_header);
996
997 /* Originate */
998 ospf6_lsa_originate_area(lsa, oa);
999
1000 return 0;
1001 }
1002
1003
1004 int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
1005 {
1006 struct ospf6_interface *oi;
1007
1008 char buffer[OSPF6_MAX_LSASIZE];
1009 struct ospf6_lsa_header *lsa_header;
1010 struct ospf6_lsa *old, *lsa;
1011
1012 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1013 struct ospf6_neighbor *on;
1014 struct ospf6_route *route;
1015 struct ospf6_prefix *op;
1016 struct listnode *i;
1017 int full_count = 0;
1018 unsigned short prefix_num = 0;
1019 struct ospf6_route_table *route_advertise;
1020 struct ospf6_link_lsa *link_lsa;
1021 char *start, *end, *current;
1022 u_int16_t type;
1023 char buf[PREFIX2STR_BUFFER];
1024
1025 oi = (struct ospf6_interface *)THREAD_ARG(thread);
1026 oi->thread_intra_prefix_lsa = NULL;
1027
1028 assert(oi->area);
1029
1030 /* find previous LSA */
1031 old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_INTRA_PREFIX),
1032 htonl(oi->interface->ifindex),
1033 oi->area->ospf6->router_id, oi->area->lsdb);
1034
1035 if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
1036 if (old)
1037 ospf6_lsa_purge(old);
1038 return 0;
1039 }
1040
1041 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1042 zlog_debug(
1043 "Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1044 oi->interface->name);
1045
1046 /* prepare buffer */
1047 memset(buffer, 0, sizeof(buffer));
1048 lsa_header = (struct ospf6_lsa_header *)buffer;
1049 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
1050 *)((caddr_t)lsa_header
1051 + sizeof(struct ospf6_lsa_header));
1052
1053 /* Fill Intra-Area-Prefix-LSA */
1054 intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_NETWORK);
1055 intra_prefix_lsa->ref_id = htonl(oi->interface->ifindex);
1056 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
1057
1058 if (oi->state != OSPF6_INTERFACE_DR) {
1059 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1060 zlog_debug(" Interface is not DR");
1061 if (old)
1062 ospf6_lsa_purge(old);
1063 return 0;
1064 }
1065
1066 full_count = 0;
1067 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on))
1068 if (on->state == OSPF6_NEIGHBOR_FULL)
1069 full_count++;
1070
1071 if (full_count == 0) {
1072 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1073 zlog_debug(" Interface is stub");
1074 if (old)
1075 ospf6_lsa_purge(old);
1076 return 0;
1077 }
1078
1079 /* connected prefix to advertise */
1080 route_advertise = ospf6_route_table_create(0, 0);
1081
1082 type = ntohs(OSPF6_LSTYPE_LINK);
1083 for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) {
1084 if (OSPF6_LSA_IS_MAXAGE(lsa))
1085 continue;
1086
1087 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1088 zlog_debug(" include prefix from %s", lsa->name);
1089
1090 if (lsa->header->adv_router != oi->area->ospf6->router_id) {
1091 on = ospf6_neighbor_lookup(lsa->header->adv_router, oi);
1092 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL) {
1093 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1094 zlog_debug(
1095 " Neighbor not found or not Full, ignore");
1096 continue;
1097 }
1098 }
1099
1100 link_lsa = (struct ospf6_link_lsa
1101 *)((caddr_t)lsa->header
1102 + sizeof(struct ospf6_lsa_header));
1103
1104 prefix_num = (unsigned short)ntohl(link_lsa->prefix_num);
1105 start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
1106 end = (char *)lsa->header + ntohs(lsa->header->length);
1107 for (current = start; current < end && prefix_num;
1108 current += OSPF6_PREFIX_SIZE(op)) {
1109 op = (struct ospf6_prefix *)current;
1110 if (op->prefix_length == 0
1111 || current + OSPF6_PREFIX_SIZE(op) > end)
1112 break;
1113
1114 route = ospf6_route_create();
1115
1116 route->type = OSPF6_DEST_TYPE_NETWORK;
1117 route->prefix.family = AF_INET6;
1118 route->prefix.prefixlen = op->prefix_length;
1119 memset(&route->prefix.u.prefix6, 0,
1120 sizeof(struct in6_addr));
1121 memcpy(&route->prefix.u.prefix6, OSPF6_PREFIX_BODY(op),
1122 OSPF6_PREFIX_SPACE(op->prefix_length));
1123
1124 route->path.origin.type = lsa->header->type;
1125 route->path.origin.id = lsa->header->id;
1126 route->path.origin.adv_router = lsa->header->adv_router;
1127 route->path.options[0] = link_lsa->options[0];
1128 route->path.options[1] = link_lsa->options[1];
1129 route->path.options[2] = link_lsa->options[2];
1130 route->path.prefix_options = op->prefix_options;
1131 route->path.area_id = oi->area->area_id;
1132 route->path.type = OSPF6_PATH_TYPE_INTRA;
1133
1134 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) {
1135 prefix2str(&route->prefix, buf, sizeof(buf));
1136 zlog_debug(" include %s", buf);
1137 }
1138
1139 ospf6_route_add(route, route_advertise);
1140 prefix_num--;
1141 }
1142 if (current != end && IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1143 zlog_debug("Trailing garbage in %s", lsa->name);
1144 }
1145
1146 op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
1147 + sizeof(struct ospf6_intra_prefix_lsa));
1148
1149 prefix_num = 0;
1150 for (route = ospf6_route_head(route_advertise); route;
1151 route = ospf6_route_best_next(route)) {
1152 op->prefix_length = route->prefix.prefixlen;
1153 op->prefix_options = route->path.prefix_options;
1154 op->prefix_metric = htons(0);
1155 memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6,
1156 OSPF6_PREFIX_SPACE(op->prefix_length));
1157 op = OSPF6_PREFIX_NEXT(op);
1158 prefix_num++;
1159 }
1160
1161 ospf6_route_table_delete(route_advertise);
1162
1163 if (prefix_num == 0) {
1164 if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
1165 zlog_debug(
1166 "Quit to Advertise Intra-Prefix: no route to advertise");
1167 return 0;
1168 }
1169
1170 intra_prefix_lsa->prefix_num = htons(prefix_num);
1171
1172 /* Fill LSA Header */
1173 lsa_header->age = 0;
1174 lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
1175 lsa_header->id = htonl(oi->interface->ifindex);
1176 lsa_header->adv_router = oi->area->ospf6->router_id;
1177 lsa_header->seqnum =
1178 ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
1179 lsa_header->adv_router, oi->area->lsdb);
1180 lsa_header->length = htons((caddr_t)op - (caddr_t)lsa_header);
1181
1182 /* LSA checksum */
1183 ospf6_lsa_checksum(lsa_header);
1184
1185 /* create LSA */
1186 lsa = ospf6_lsa_create(lsa_header);
1187
1188 /* Originate */
1189 ospf6_lsa_originate_area(lsa, oi->area);
1190
1191 return 0;
1192 }
1193
1194 void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
1195 {
1196 struct ospf6_area *oa;
1197 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1198 struct prefix ls_prefix;
1199 struct ospf6_route *route, *ls_entry;
1200 int prefix_num;
1201 struct ospf6_prefix *op;
1202 char *start, *current, *end;
1203 char buf[PREFIX2STR_BUFFER];
1204 struct interface *ifp;
1205 int direct_connect = 0;
1206
1207 if (OSPF6_LSA_IS_MAXAGE(lsa))
1208 return;
1209
1210 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1211 zlog_debug("%s found", lsa->name);
1212
1213 oa = OSPF6_AREA(lsa->lsdb->data);
1214
1215 intra_prefix_lsa =
1216 (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END(
1217 lsa->header);
1218 if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER))
1219 ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router,
1220 htonl(0), &ls_prefix);
1221 else if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK))
1222 ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router,
1223 intra_prefix_lsa->ref_id, &ls_prefix);
1224 else {
1225 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1226 zlog_debug("Unknown reference LS-type: %#hx",
1227 ntohs(intra_prefix_lsa->ref_type));
1228 return;
1229 }
1230
1231 ls_entry = ospf6_route_lookup(&ls_prefix, oa->spf_table);
1232 if (ls_entry == NULL) {
1233 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
1234 ospf6_linkstate_prefix2str(&ls_prefix, buf,
1235 sizeof(buf));
1236 zlog_debug("LS entry does not exist: %s", buf);
1237 }
1238 return;
1239 }
1240
1241 if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) {
1242 /* the intra-prefix are directly connected */
1243 direct_connect = 1;
1244 }
1245
1246 prefix_num = ntohs(intra_prefix_lsa->prefix_num);
1247 start = (caddr_t)intra_prefix_lsa
1248 + sizeof(struct ospf6_intra_prefix_lsa);
1249 end = OSPF6_LSA_END(lsa->header);
1250 for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) {
1251 op = (struct ospf6_prefix *)current;
1252 if (prefix_num == 0)
1253 break;
1254 if (end < current + OSPF6_PREFIX_SIZE(op))
1255 break;
1256
1257 /* Appendix A.4.1.1 */
1258 if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU)) {
1259 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
1260 ospf6_linkstate_prefix2str(
1261 (struct prefix *)OSPF6_PREFIX_BODY(op),
1262 buf, sizeof(buf));
1263 zlog_debug(
1264 "%s: Skipping Prefix %s has NU option set",
1265 __func__, buf);
1266 }
1267 continue;
1268 }
1269
1270 route = ospf6_route_create();
1271
1272 memset(&route->prefix, 0, sizeof(struct prefix));
1273 route->prefix.family = AF_INET6;
1274 route->prefix.prefixlen = op->prefix_length;
1275 ospf6_prefix_in6_addr(&route->prefix.u.prefix6, op);
1276
1277 route->type = OSPF6_DEST_TYPE_NETWORK;
1278 route->path.origin.type = lsa->header->type;
1279 route->path.origin.id = lsa->header->id;
1280 route->path.origin.adv_router = lsa->header->adv_router;
1281 route->path.prefix_options = op->prefix_options;
1282 route->path.area_id = oa->area_id;
1283 route->path.type = OSPF6_PATH_TYPE_INTRA;
1284 route->path.metric_type = 1;
1285 route->path.cost =
1286 ls_entry->path.cost + ntohs(op->prefix_metric);
1287
1288 if (direct_connect) {
1289 ifp = if_lookup_prefix(&route->prefix, VRF_DEFAULT);
1290 if (ifp)
1291 ospf6_route_add_nexthop(route, ifp->ifindex,
1292 NULL);
1293 } else {
1294 ospf6_route_copy_nexthops(route, ls_entry);
1295 }
1296
1297 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
1298 prefix2str(&route->prefix, buf, sizeof(buf));
1299 zlog_debug(" add %s", buf);
1300 }
1301
1302 ospf6_route_add(route, oa->route_table);
1303 prefix_num--;
1304 }
1305
1306 if (current != end && IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1307 zlog_debug("Trailing garbage ignored");
1308 }
1309
1310 void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa)
1311 {
1312 struct ospf6_area *oa;
1313 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1314 struct prefix prefix;
1315 struct ospf6_route *route, *nroute;
1316 int prefix_num;
1317 struct ospf6_prefix *op;
1318 char *start, *current, *end;
1319 char buf[PREFIX2STR_BUFFER];
1320
1321 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1322 zlog_debug("%s disappearing", lsa->name);
1323
1324 oa = OSPF6_AREA(lsa->lsdb->data);
1325
1326 intra_prefix_lsa =
1327 (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END(
1328 lsa->header);
1329
1330 prefix_num = ntohs(intra_prefix_lsa->prefix_num);
1331 start = (caddr_t)intra_prefix_lsa
1332 + sizeof(struct ospf6_intra_prefix_lsa);
1333 end = OSPF6_LSA_END(lsa->header);
1334 for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) {
1335 op = (struct ospf6_prefix *)current;
1336 if (prefix_num == 0)
1337 break;
1338 if (end < current + OSPF6_PREFIX_SIZE(op))
1339 break;
1340 prefix_num--;
1341
1342 memset(&prefix, 0, sizeof(struct prefix));
1343 prefix.family = AF_INET6;
1344 prefix.prefixlen = op->prefix_length;
1345 ospf6_prefix_in6_addr(&prefix.u.prefix6, op);
1346
1347 route = ospf6_route_lookup(&prefix, oa->route_table);
1348 if (route == NULL)
1349 continue;
1350
1351 for (ospf6_route_lock(route);
1352 route && ospf6_route_is_prefix(&prefix, route);
1353 route = nroute) {
1354 nroute = ospf6_route_next(route);
1355 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1356 continue;
1357 if (route->path.area_id != oa->area_id)
1358 continue;
1359 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1360 continue;
1361 if (route->path.origin.type != lsa->header->type
1362 || route->path.origin.id != lsa->header->id
1363 || route->path.origin.adv_router
1364 != lsa->header->adv_router)
1365 continue;
1366
1367 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
1368 prefix2str(&route->prefix, buf, sizeof(buf));
1369 zlog_debug("remove %s", buf);
1370 }
1371 ospf6_route_remove(route, oa->route_table);
1372 }
1373 if (route)
1374 ospf6_route_unlock(route);
1375 }
1376
1377 if (current != end && IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1378 zlog_debug("Trailing garbage ignored");
1379 }
1380
1381 void ospf6_intra_route_calculation(struct ospf6_area *oa)
1382 {
1383 struct ospf6_route *route, *nroute;
1384 u_int16_t type;
1385 struct ospf6_lsa *lsa;
1386 void (*hook_add)(struct ospf6_route *) = NULL;
1387 void (*hook_remove)(struct ospf6_route *) = NULL;
1388
1389 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1390 zlog_debug("Re-examin intra-routes for area %s", oa->name);
1391
1392 hook_add = oa->route_table->hook_add;
1393 hook_remove = oa->route_table->hook_remove;
1394 oa->route_table->hook_add = NULL;
1395 oa->route_table->hook_remove = NULL;
1396
1397 for (route = ospf6_route_head(oa->route_table); route;
1398 route = ospf6_route_next(route))
1399 route->flag = OSPF6_ROUTE_REMOVE;
1400
1401 type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
1402 for (ALL_LSDB_TYPED(oa->lsdb, type, lsa))
1403 ospf6_intra_prefix_lsa_add(lsa);
1404
1405 oa->route_table->hook_add = hook_add;
1406 oa->route_table->hook_remove = hook_remove;
1407
1408 for (route = ospf6_route_head(oa->route_table); route; route = nroute) {
1409 nroute = ospf6_route_next(route);
1410 if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE)
1411 && CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD)) {
1412 UNSET_FLAG(route->flag, OSPF6_ROUTE_REMOVE);
1413 UNSET_FLAG(route->flag, OSPF6_ROUTE_ADD);
1414 }
1415
1416 if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE))
1417 ospf6_route_remove(route, oa->route_table);
1418 else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD)
1419 || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) {
1420 if (hook_add)
1421 (*hook_add)(route);
1422 route->flag = 0;
1423 } else {
1424 /* Redo the summaries as things might have changed */
1425 ospf6_abr_originate_summary(route);
1426 route->flag = 0;
1427 }
1428 }
1429
1430 if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
1431 zlog_debug("Re-examin intra-routes for area %s: Done",
1432 oa->name);
1433 }
1434
1435 static void ospf6_brouter_debug_print(struct ospf6_route *brouter)
1436 {
1437 u_int32_t brouter_id;
1438 char brouter_name[16];
1439 char area_name[16];
1440 char destination[64];
1441 char installed[16], changed[16];
1442 struct timeval now, res;
1443 char id[16], adv_router[16];
1444 char capa[16], options[16];
1445
1446 brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix);
1447 inet_ntop(AF_INET, &brouter_id, brouter_name, sizeof(brouter_name));
1448 inet_ntop(AF_INET, &brouter->path.area_id, area_name,
1449 sizeof(area_name));
1450 ospf6_linkstate_prefix2str(&brouter->prefix, destination,
1451 sizeof(destination));
1452
1453 monotime(&now);
1454 timersub(&now, &brouter->installed, &res);
1455 timerstring(&res, installed, sizeof(installed));
1456
1457 monotime(&now);
1458 timersub(&now, &brouter->changed, &res);
1459 timerstring(&res, changed, sizeof(changed));
1460
1461 inet_ntop(AF_INET, &brouter->path.origin.id, id, sizeof(id));
1462 inet_ntop(AF_INET, &brouter->path.origin.adv_router, adv_router,
1463 sizeof(adv_router));
1464
1465 ospf6_options_printbuf(brouter->path.options, options, sizeof(options));
1466 ospf6_capability_printbuf(brouter->path.router_bits, capa,
1467 sizeof(capa));
1468
1469 zlog_info("Brouter: %s via area %s", brouter_name, area_name);
1470 zlog_info(" memory: prev: %p this: %p next: %p parent rnode: %p",
1471 (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
1472 (void *)brouter->rnode);
1473 zlog_info(" type: %d prefix: %s installed: %s changed: %s",
1474 brouter->type, destination, installed, changed);
1475 zlog_info(" lock: %d flags: %s%s%s%s", brouter->lock,
1476 (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1477 (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1478 (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1479 (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1480 zlog_info(" path type: %s ls-origin %s id: %s adv-router %s",
1481 OSPF6_PATH_TYPE_NAME(brouter->path.type),
1482 ospf6_lstype_name(brouter->path.origin.type), id, adv_router);
1483 zlog_info(" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1484 options, capa, brouter->path.metric_type, brouter->path.cost,
1485 brouter->path.u.cost_e2);
1486 }
1487
1488 void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
1489 {
1490 struct ospf6_route *brouter, *nbrouter, *copy;
1491 void (*hook_add)(struct ospf6_route *) = NULL;
1492 void (*hook_remove)(struct ospf6_route *) = NULL;
1493 u_int32_t brouter_id;
1494 char brouter_name[16];
1495
1496 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id))
1497 zlog_info("border-router calculation for area %s", oa->name);
1498
1499 hook_add = oa->ospf6->brouter_table->hook_add;
1500 hook_remove = oa->ospf6->brouter_table->hook_remove;
1501 oa->ospf6->brouter_table->hook_add = NULL;
1502 oa->ospf6->brouter_table->hook_remove = NULL;
1503
1504 /* withdraw the previous router entries for the area */
1505 for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter;
1506 brouter = ospf6_route_next(brouter)) {
1507 brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix);
1508 inet_ntop(AF_INET, &brouter_id, brouter_name,
1509 sizeof(brouter_name));
1510 if (brouter->path.area_id != oa->area_id)
1511 continue;
1512 SET_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE);
1513
1514 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id)
1515 || IS_OSPF6_DEBUG_ROUTE(MEMORY)) {
1516 zlog_info("%p: mark as removing: area %s brouter %s",
1517 (void *)brouter, oa->name, brouter_name);
1518 ospf6_brouter_debug_print(brouter);
1519 }
1520 }
1521
1522 for (brouter = ospf6_route_head(oa->spf_table); brouter;
1523 brouter = ospf6_route_next(brouter)) {
1524 brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix);
1525 inet_ntop(AF_INET, &brouter_id, brouter_name,
1526 sizeof(brouter_name));
1527
1528 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
1529 continue;
1530 if (ospf6_linkstate_prefix_id(&brouter->prefix) != htonl(0))
1531 continue;
1532 if (!CHECK_FLAG(brouter->path.router_bits, OSPF6_ROUTER_BIT_E)
1533 && !CHECK_FLAG(brouter->path.router_bits,
1534 OSPF6_ROUTER_BIT_B))
1535 continue;
1536
1537 if (!OSPF6_OPT_ISSET(brouter->path.options, OSPF6_OPT_V6)
1538 || !OSPF6_OPT_ISSET(brouter->path.options, OSPF6_OPT_R))
1539 continue;
1540
1541 copy = ospf6_route_copy(brouter);
1542 copy->type = OSPF6_DEST_TYPE_ROUTER;
1543 copy->path.area_id = oa->area_id;
1544 ospf6_route_add(copy, oa->ospf6->brouter_table);
1545
1546 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id)
1547 || IS_OSPF6_DEBUG_ROUTE(MEMORY)) {
1548 zlog_info("%p: transfer: area %s brouter %s",
1549 (void *)brouter, oa->name, brouter_name);
1550 ospf6_brouter_debug_print(brouter);
1551 }
1552 }
1553
1554 oa->ospf6->brouter_table->hook_add = hook_add;
1555 oa->ospf6->brouter_table->hook_remove = hook_remove;
1556
1557 for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter;
1558 brouter = nbrouter) {
1559 nbrouter = ospf6_route_next(brouter);
1560 brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix);
1561 inet_ntop(AF_INET, &brouter_id, brouter_name,
1562 sizeof(brouter_name));
1563
1564 if (brouter->path.area_id != oa->area_id)
1565 continue;
1566
1567 if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
1568 continue;
1569
1570 if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE)
1571 && CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)) {
1572 UNSET_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE);
1573 UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD);
1574 }
1575
1576 if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE)) {
1577 if (IS_OSPF6_DEBUG_BROUTER
1578 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1579 brouter_id)
1580 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1581 oa->area_id))
1582 zlog_info("brouter %s disappears via area %s",
1583 brouter_name, oa->name);
1584 ospf6_route_remove(brouter, oa->ospf6->brouter_table);
1585 brouter = NULL;
1586 } else if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)
1587 || CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE)) {
1588 if (IS_OSPF6_DEBUG_BROUTER
1589 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1590 brouter_id)
1591 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1592 oa->area_id))
1593 zlog_info("brouter %s appears via area %s",
1594 brouter_name, oa->name);
1595
1596 /* newly added */
1597 if (hook_add)
1598 (*hook_add)(brouter);
1599 } else {
1600 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
1601 brouter_id)
1602 || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(
1603 oa->area_id))
1604 zlog_info("brouter %s still exists via area %s",
1605 brouter_name, oa->name);
1606 /* But re-originate summaries */
1607 ospf6_abr_originate_summary(brouter);
1608 }
1609
1610 if (brouter) {
1611 UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD);
1612 UNSET_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE);
1613 }
1614 }
1615
1616 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id))
1617 zlog_info("border-router calculation for area %s: done",
1618 oa->name);
1619 }
1620
1621 struct ospf6_lsa_handler router_handler = {OSPF6_LSTYPE_ROUTER, "Router", "Rtr",
1622 ospf6_router_lsa_show,
1623 ospf6_router_lsa_get_nbr_id};
1624
1625 struct ospf6_lsa_handler network_handler = {OSPF6_LSTYPE_NETWORK, "Network",
1626 "Net", ospf6_network_lsa_show,
1627 ospf6_network_lsa_get_ar_id};
1628
1629 struct ospf6_lsa_handler link_handler = {OSPF6_LSTYPE_LINK, "Link", "Lnk",
1630 ospf6_link_lsa_show,
1631 ospf6_link_lsa_get_prefix_str};
1632
1633 struct ospf6_lsa_handler intra_prefix_handler = {
1634 OSPF6_LSTYPE_INTRA_PREFIX, "Intra-Prefix", "INP",
1635 ospf6_intra_prefix_lsa_show, ospf6_intra_prefix_lsa_get_prefix_str};
1636
1637 void ospf6_intra_init(void)
1638 {
1639 ospf6_install_lsa_handler(&router_handler);
1640 ospf6_install_lsa_handler(&network_handler);
1641 ospf6_install_lsa_handler(&link_handler);
1642 ospf6_install_lsa_handler(&intra_prefix_handler);
1643 }
1644
1645 DEFUN (debug_ospf6_brouter,
1646 debug_ospf6_brouter_cmd,
1647 "debug ospf6 border-routers",
1648 DEBUG_STR
1649 OSPF6_STR
1650 "Debug border router\n"
1651 )
1652 {
1653 OSPF6_DEBUG_BROUTER_ON();
1654 return CMD_SUCCESS;
1655 }
1656
1657 DEFUN (no_debug_ospf6_brouter,
1658 no_debug_ospf6_brouter_cmd,
1659 "no debug ospf6 border-routers",
1660 NO_STR
1661 DEBUG_STR
1662 OSPF6_STR
1663 "Debug border router\n"
1664 )
1665 {
1666 OSPF6_DEBUG_BROUTER_OFF();
1667 return CMD_SUCCESS;
1668 }
1669
1670 DEFUN (debug_ospf6_brouter_router,
1671 debug_ospf6_brouter_router_cmd,
1672 "debug ospf6 border-routers router-id A.B.C.D",
1673 DEBUG_STR
1674 OSPF6_STR
1675 "Debug border router\n"
1676 "Debug specific border router\n"
1677 "Specify border-router's router-id\n"
1678 )
1679 {
1680 int idx_ipv4 = 4;
1681 u_int32_t router_id;
1682 inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id);
1683 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON(router_id);
1684 return CMD_SUCCESS;
1685 }
1686
1687 DEFUN (no_debug_ospf6_brouter_router,
1688 no_debug_ospf6_brouter_router_cmd,
1689 "no debug ospf6 border-routers router-id",
1690 NO_STR
1691 DEBUG_STR
1692 OSPF6_STR
1693 "Debug border router\n"
1694 "Debug specific border router\n"
1695 )
1696 {
1697 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF();
1698 return CMD_SUCCESS;
1699 }
1700
1701 DEFUN (debug_ospf6_brouter_area,
1702 debug_ospf6_brouter_area_cmd,
1703 "debug ospf6 border-routers area-id A.B.C.D",
1704 DEBUG_STR
1705 OSPF6_STR
1706 "Debug border router\n"
1707 "Debug border routers in specific Area\n"
1708 "Specify Area-ID\n"
1709 )
1710 {
1711 int idx_ipv4 = 4;
1712 u_int32_t area_id;
1713 inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id);
1714 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON(area_id);
1715 return CMD_SUCCESS;
1716 }
1717
1718 DEFUN (no_debug_ospf6_brouter_area,
1719 no_debug_ospf6_brouter_area_cmd,
1720 "no debug ospf6 border-routers area-id",
1721 NO_STR
1722 DEBUG_STR
1723 OSPF6_STR
1724 "Debug border router\n"
1725 "Debug border routers in specific Area\n"
1726 )
1727 {
1728 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF();
1729 return CMD_SUCCESS;
1730 }
1731
1732 int config_write_ospf6_debug_brouter(struct vty *vty)
1733 {
1734 char buf[16];
1735 if (IS_OSPF6_DEBUG_BROUTER)
1736 vty_out(vty, "debug ospf6 border-routers\n");
1737 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) {
1738 inet_ntop(AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1739 buf, sizeof(buf));
1740 vty_out(vty, "debug ospf6 border-routers router-id %s\n", buf);
1741 }
1742 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) {
1743 inet_ntop(AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1744 buf, sizeof(buf));
1745 vty_out(vty, "debug ospf6 border-routers area-id %s\n", buf);
1746 }
1747 return 0;
1748 }
1749
1750 void install_element_ospf6_debug_brouter(void)
1751 {
1752 install_element(ENABLE_NODE, &debug_ospf6_brouter_cmd);
1753 install_element(ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1754 install_element(ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1755 install_element(ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1756 install_element(ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1757 install_element(ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1758 install_element(CONFIG_NODE, &debug_ospf6_brouter_cmd);
1759 install_element(CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1760 install_element(CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1761 install_element(CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1762 install_element(CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1763 install_element(CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
1764 }