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