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