2 * Copyright (C) 1999 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
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.
21 /* ospf6 routing table calculation function */
29 #include "ospf6_proto.h"
30 #include "ospf6_prefix.h"
31 #include "ospf6_route.h"
37 ospf6_route_info_is_same_attribute (struct ospf6_route_info
*new,
38 struct ospf6_route_info
*old
)
40 if (new->capability_bits
!= old
->capability_bits
)
42 if (new->opt_capability
[0] != old
->opt_capability
[0])
44 if (new->opt_capability
[1] != old
->opt_capability
[1])
46 if (new->opt_capability
[2] != old
->opt_capability
[2])
48 if (new->area_id
!= old
->area_id
)
50 if (new->path_type
!= old
->path_type
)
52 if (new->cost
!= old
->cost
)
54 if (new->cost_e2
!= old
->cost_e2
)
56 if (new->origin_id
!= old
->origin_id
)
58 if (new->origin_adv_router
!= old
->origin_adv_router
)
64 ospf6_route_info_is_same (struct ospf6_route_info
*ri1
,
65 struct ospf6_route_info
*ri2
)
68 struct ospf6_nexthop
*nexthop
;
70 if (! ospf6_route_info_is_same_attribute (ri1
, ri2
))
73 for (node
= listhead (ri1
->nexthop_list
); node
; nextnode (node
))
75 nexthop
= (struct ospf6_nexthop
*) getdata (node
);
76 if (listnode_lookup (ri2
->nexthop_list
, nexthop
) == NULL
)
80 for (node
= listhead (ri2
->nexthop_list
); node
; nextnode (node
))
82 nexthop
= (struct ospf6_nexthop
*) getdata (node
);
83 if (listnode_lookup (ri1
->nexthop_list
, nexthop
) == NULL
)
90 struct ospf6_nexthop
*
91 ospf6_nexthop_create (unsigned int ifindex
, struct in6_addr
*ipaddr
,
95 struct ospf6_nexthop
*nexthop
, *new;
98 inet_ntop (AF_INET6
, ipaddr
, buf
, sizeof (buf
));
100 for (node
= listhead (ospf6
->nexthop_list
); node
; nextnode (node
))
102 nexthop
= (struct ospf6_nexthop
*) getdata (node
);
103 if (nexthop
->ifindex
!= ifindex
)
105 if (memcmp (&nexthop
->ipaddr
, ipaddr
, sizeof (struct in6_addr
)) != 0)
107 if (nexthop
->adv_router
!= adv_router
)
114 new = (struct ospf6_nexthop
*) XMALLOC (MTYPE_OSPF6_NEXTHOP
,
115 sizeof (struct ospf6_nexthop
));
118 zlog_err ("ROUTE: Can't allocate memory for nexthop");
119 return (struct ospf6_nexthop
*) NULL
;
121 memset (new, 0, sizeof (struct ospf6_nexthop
));
122 new->ifindex
= ifindex
;
123 memcpy (&new->ipaddr
, ipaddr
, sizeof (struct in6_addr
));
124 new->adv_router
= adv_router
;
127 listnode_add (ospf6
->nexthop_list
, new);
132 ospf6_nexthop_delete (struct ospf6_nexthop
*nexthop
)
135 if (nexthop
->lock
== 0)
137 listnode_delete (ospf6
->nexthop_list
, nexthop
);
138 XFREE (MTYPE_OSPF6_NEXTHOP
, nexthop
);
142 static struct ospf6_route_info
*
143 ospf6_route_info_create (u_char opt_capability
[3], u_char capability_bits
,
144 u_int32_t area_id
, u_char path_type
,
145 u_int32_t cost
, u_int32_t cost_e2
,
146 u_int32_t origin_id
, u_int32_t origin_adv_router
,
150 struct ospf6_route_info
*new;
151 struct ospf6_nexthop
*n
, *nexthop
;
153 new = (struct ospf6_route_info
*) XMALLOC (MTYPE_OSPF6_ROUTE
,
154 sizeof (struct ospf6_route_info
));
157 zlog_err ("ROUTE: Can't allocate memory for route info");
158 return (struct ospf6_route_info
*) NULL
;
160 memset (new, 0, sizeof (struct ospf6_route_info
));
162 new->opt_capability
[0] = opt_capability
[0];
163 new->opt_capability
[1] = opt_capability
[1];
164 new->opt_capability
[2] = opt_capability
[2];
165 new->capability_bits
= capability_bits
;
166 new->area_id
= area_id
;
167 new->path_type
= path_type
;
169 new->cost_e2
= cost_e2
;
170 new->origin_id
= origin_id
;
171 new->origin_adv_router
= origin_adv_router
;
172 new->nexthop_list
= list_new ();
175 for (node
= listhead (nexthop_list
); node
; nextnode (node
))
177 n
= (struct ospf6_nexthop
*) getdata (node
);
178 nexthop
= ospf6_nexthop_create (n
->ifindex
, &n
->ipaddr
, n
->adv_router
);
179 listnode_add (new->nexthop_list
, nexthop
);
186 ospf6_route_info_delete (struct ospf6_route_info
*route_info
)
189 struct ospf6_nexthop
*nexthop
;
191 for (node
= listhead (route_info
->nexthop_list
); node
; nextnode (node
))
193 nexthop
= (struct ospf6_nexthop
*) getdata (node
);
194 ospf6_nexthop_delete (nexthop
);
196 list_delete (route_info
->nexthop_list
);
197 XFREE (MTYPE_OSPF6_ROUTE
, route_info
);
201 ospf6_route_info_merge (struct ospf6_route_info
*new,
202 struct ospf6_route_info
*old
)
205 struct ospf6_nexthop
*nexthop
;
207 for (node
= listhead (new->nexthop_list
); node
; nextnode (node
))
209 nexthop
= (struct ospf6_nexthop
*) getdata (node
);
210 if (listnode_lookup (old
->nexthop_list
, nexthop
))
212 listnode_add (old
->nexthop_list
, nexthop
);
217 /* RFC2328 section 11 */
219 ospf6_route_info_is_new_prefered (struct ospf6_route_info
*new,
220 struct ospf6_route_info
*old
)
222 if (! CHECK_FLAG (old
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
))
225 if (new->path_type
< old
->path_type
)
227 else if (new->path_type
> old
->path_type
)
230 if (new->cost_e2
< old
->cost_e2
)
232 else if (new->cost_e2
> old
->cost_e2
)
235 if (new->cost
< old
->cost
)
237 else if (new->cost
> old
->cost
)
240 zlog_err ("ROUTE: Can't decide if the new route info is prefered");
244 struct ospf6_route_info
*
245 ospf6_route_create (struct prefix
*destination
, char *string
,
246 u_char opt_capability
[3], u_char capability_bits
,
247 u_int32_t area_id
, u_char path_type
,
248 u_int32_t cost
, u_int32_t cost_e2
,
249 u_int32_t origin_id
, u_int32_t origin_adv_router
,
251 struct route_table
*table
)
253 struct route_node
*route_node
;
254 struct ospf6_route_info
*new, *old
;
256 struct ospf6_route_info
*route_info
;
258 new = ospf6_route_info_create (opt_capability
, capability_bits
,
259 area_id
, path_type
, cost
, cost_e2
,
260 origin_id
, origin_adv_router
, nexthop_list
);
263 zlog_err ("ROUTE: Can't create route info for %s", string
);
264 return (struct ospf6_route_info
*) NULL
;
267 route_node
= route_node_get (table
, destination
);
268 old
= route_node
->info
;
272 /* this is the first route for this destination */
273 if (IS_OSPF6_DUMP_ROUTE
)
274 zlog_info ("ROUTE: route created: %s", string
);
276 SET_FLAG (new->flag
, OSPF6_ROUTE_FLAG_ACTIVE
);
277 route_node
->info
= new;
281 route_info
= (struct ospf6_route_info
*) NULL
;
285 if (IS_OSPF6_DUMP_ROUTE
)
286 zlog_info ("ROUTE: route already exists: %s", string
);
289 if (ospf6_route_info_is_same (new, old
))
291 /* the same entry exists, nothing to do */
293 if (IS_OSPF6_DUMP_ROUTE
)
294 zlog_info ("ROUTE: route untouched: %s", string
);
296 ospf6_route_info_delete (new);
299 else if (ospf6_route_info_is_same_attribute (new, old
))
301 /* merge new's nexthop to old's */
302 if (IS_OSPF6_DUMP_ROUTE
)
303 zlog_info ("ROUTE: route merged: %s", string
);
304 ospf6_route_info_merge (new, old
);
305 ospf6_route_info_delete (new);
308 else if (ospf6_route_info_is_new_prefered (new, old
))
310 /* new route is prefered, replace with old one */
311 if (IS_OSPF6_DUMP_ROUTE
)
312 zlog_info ("ROUTE: route changed: %s", string
);
313 ospf6_route_info_delete (old
);
318 /* there's already better route for this destination */
320 if (IS_OSPF6_DUMP_ROUTE
)
321 zlog_info ("ROUTE: route rejected: %s", string
);
323 ospf6_route_info_delete (new);
327 SET_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
);
328 route_node
->info
= route_info
;
333 ospf6_route_delete (struct prefix
*destination
,
334 struct route_table
*table
)
336 struct route_node
*route_node
;
337 struct ospf6_route_info
*route_info
;
341 prefix2str (destination
, pstring
, sizeof (pstring
));
343 route_node
= route_node_get (table
, destination
);
344 route_info
= (struct ospf6_route_info
*) route_node
->info
;
347 if (IS_OSPF6_DUMP_ROUTE
)
348 zlog_info ("ROUTE: Can't delete route %s: doesn't exist", pstring
);
352 if (CHECK_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ZEBRA_SYNC
))
354 UNSET_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
);
356 if (IS_OSPF6_DUMP_ROUTE
)
357 zlog_info ("ROUTE: delete sync'ed route: %s", pstring
);
359 if (IS_OSPF6_DUMP_ROUTE
)
360 zlog_info ("ROUTE: route delete: %s", pstring
);
362 ospf6_zebra_route_update ((struct prefix_ipv6
*) destination
,
367 if (IS_OSPF6_DUMP_ROUTE
)
368 zlog_info ("ROUTE: delete route %s", pstring
);
371 ospf6_route_info_delete (route_info
);
372 route_node
->info
= NULL
;
376 ospf6_route_delete_all (struct route_table
*table
)
378 struct route_node
*node
;
380 for (node
= route_top (table
); node
; node
= route_next (node
))
385 ospf6_route_delete (&node
->p
, table
);
390 ospf6_route_intra_area (struct prefix_ls
*d
, struct ospf6_route_info
*ri
,
391 struct ospf6_area
*o6a
)
394 u_int16_t type
, cost
;
395 struct ospf6_lsa
*lsa
;
396 struct ospf6_intra_area_prefix_lsa
*intra_prefix_lsa
;
397 struct ospf6_prefix
*ospf6_prefix
;
398 struct prefix_ipv6 prefix
;
399 char buf
[64], node_string
[64], prefix_string
[64];
400 struct ospf6_lsdb_node
*node
;
402 if (d
->id
.s_addr
== 0)
403 type
= htons (OSPF6_LSA_TYPE_ROUTER
);
405 type
= htons (OSPF6_LSA_TYPE_NETWORK
);
408 inet_ntop (AF_INET
, &d
->adv_router
, buf
, sizeof (buf
));
409 snprintf (node_string
, sizeof (node_string
),
410 "%s[%lu]", buf
, (unsigned long) ntohl (d
->id
.s_addr
));
412 if (IS_OSPF6_DUMP_ROUTE
)
413 zlog_info ("ROUTE: Calculate Route for %s", node_string
);
415 /* Foreach appropriate Intra-Area-Prefix-LSA */
416 for (node
= ospf6_lsdb_head (o6a
->lsdb
); node
; node
= ospf6_lsdb_next (node
))
419 if (ospf6_lsa_is_maxage (lsa
))
422 if (lsa
->header
->type
!= htons (OSPF6_LSA_TYPE_INTRA_PREFIX
))
424 if (lsa
->header
->adv_router
!= d
->adv_router
.s_addr
)
427 if (IS_OSPF6_DUMP_ROUTE
)
428 zlog_info ("ROUTE: Check %s", lsa
->str
);
430 /* check LS Reference */
431 intra_prefix_lsa
= (struct ospf6_intra_area_prefix_lsa
*)
434 if (intra_prefix_lsa
->refer_lstype
== htons (OSPF6_LSA_TYPE_NETWORK
)
435 && ntohs (type
) == OSPF6_LSA_TYPE_ROUTER
)
437 zlog_info ("Network Reference while Router");
440 if (intra_prefix_lsa
->refer_lstype
== htons (OSPF6_LSA_TYPE_ROUTER
)
441 && ntohs (type
) == OSPF6_LSA_TYPE_NETWORK
)
443 zlog_info ("Router Reference while Network ");
447 /* If Network LSA and Reference-ID wrong */
448 if (intra_prefix_lsa
->refer_lstype
== htons (OSPF6_LSA_TYPE_NETWORK
)
449 && intra_prefix_lsa
->refer_lsid
!= 0
450 && intra_prefix_lsa
->refer_lsid
!= d
->id
.s_addr
)
452 if (IS_OSPF6_DUMP_ROUTE
)
454 zlog_info ("ROUTE: Network Reference-ID wrong: %s <-> %s",
455 node_string
, lsa
->str
);
456 zlog_info ("ROUTE: intra_prefix_lsa->refer_lsid: %d\n",
457 ntohl (intra_prefix_lsa
->refer_lsid
));
458 zlog_info ("ROUTE: d->id.s_addr : %d\n",
459 ntohl (d
->id
.s_addr
));
464 /* If Reference-Type is Router and the entry not indicate Router */
465 if (intra_prefix_lsa
->refer_lstype
== htons (OSPF6_LSA_TYPE_ROUTER
)
466 && d
->id
.s_addr
!= 0)
468 if (IS_OSPF6_DUMP_ROUTE
)
469 zlog_info ("ROUTE: Reference-Type (Router) wrong: %s <-> %s",
470 node_string
, lsa
->str
);
471 zlog_info ("ROUTE: intra_prefix_lsa->refer_lsid: %d\n",
472 ntohl (intra_prefix_lsa
->refer_lsid
));
473 zlog_info ("ROUTE: d->id.s_addr : %d\n", ntohl (d
->id
.s_addr
));
477 /* If Reference-Type is Network and the entry not indicate Network */
478 if (intra_prefix_lsa
->refer_lstype
== htons (OSPF6_LSA_TYPE_NETWORK
)
479 && d
->id
.s_addr
== 0)
481 if (IS_OSPF6_DUMP_ROUTE
)
482 zlog_info ("ROUTE: Reference-Type (Network) wrong: %s <-> %s",
483 node_string
, lsa
->str
);
487 if (IS_OSPF6_DUMP_ROUTE
)
488 zlog_info ("ROUTE: %s: Prefix LSA %s", node_string
, lsa
->str
);
490 /* for each ospf6 prefixes */
491 ospf6_prefix
= (struct ospf6_prefix
*) (intra_prefix_lsa
+ 1);
492 for (i
= 0; i
< ntohs (intra_prefix_lsa
->prefix_number
); i
++)
494 memset (&prefix
, 0, sizeof (struct prefix_ipv6
));
495 prefix
.family
= AF_INET6
;
496 ospf6_prefix_in6_addr (ospf6_prefix
, &prefix
.prefix
);
497 prefix
.prefixlen
= ospf6_prefix
->prefix_length
;
498 cost
= ri
->cost
+ ntohs (ospf6_prefix
->prefix_metric
);
500 prefix2str ((struct prefix
*) &prefix
, prefix_string
,
501 sizeof (prefix_string
));
503 if (IS_OSPF6_DUMP_ROUTE
)
504 zlog_info ("ROUTE: route install %s cost %d", prefix_string
, cost
);
506 ospf6_route_create ((struct prefix
*) &prefix
, prefix_string
,
507 ri
->opt_capability
, 0, ri
->area_id
,
508 OSPF6_ROUTE_PATH_TYPE_INTRA
,
509 cost
, 0, ri
->origin_id
, ri
->origin_adv_router
,
510 ri
->nexthop_list
, ospf6
->route_table
);
512 /* examin next prefix */
513 ospf6_prefix
= OSPF6_NEXT_PREFIX (ospf6_prefix
);
519 ospf6_route_calculation_intra_area (struct ospf6_area
*o6a
)
521 struct route_node
*node
;
522 struct prefix_ls
*destination
;
523 struct ospf6_route_info
*info
;
525 for (node
= route_top (o6a
->table_topology
); node
; node
= route_next (node
))
527 destination
= (struct prefix_ls
*) &node
->p
;
528 info
= (struct ospf6_route_info
*) node
->info
;
531 ospf6_route_intra_area (destination
, info
, o6a
);
536 ospf6_route_calculation_inter_area (struct ospf6_area
*o6a
)
540 struct ospf6_route_info
*
541 ospf6_route_asbr_entry (u_int32_t adv_router
, struct ospf6
*o6
)
544 struct route_node
*r_node
;
545 struct ospf6_area
*o6a
;
547 struct ospf6_route_info
*ri
;
549 for (l_node
= listhead (o6
->area_list
); l_node
; nextnode (l_node
))
551 o6a
= (struct ospf6_area
*) getdata (l_node
);
552 d
.adv_router
.s_addr
= adv_router
;
553 d
.id
.s_addr
= htonl (0);
557 r_node
= route_node_lookup (o6a
->table_topology
, (struct prefix
*) &d
);
559 return (struct ospf6_route_info
*) NULL
;
561 ri
= (struct ospf6_route_info
*) r_node
->info
;
563 return (struct ospf6_route_info
*) NULL
;
565 if (ri
->capability_bits
& OSPF6_ROUTER_LSA_BIT_E
)
568 return (struct ospf6_route_info
*) NULL
;
570 return (struct ospf6_route_info
*) NULL
;
573 /* RFC2328 section 16.4 */
575 ospf6_route_external (struct ospf6_lsa
*lsa
)
577 struct ospf6_lsa_header
*lsa_header
;
578 struct ospf6_as_external_lsa
*as_external_lsa
;
579 struct in6_addr
*forwarding_address
;
580 struct prefix_ipv6 forwarding
, prefix
;
581 struct route_node
*node
;
582 struct ospf6_route_info
*ri
;
583 u_int16_t cost1
, cost2
;
586 u_char opt_capability
[3];
588 /* prepare destination prefix first */
589 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
590 as_external_lsa
= (struct ospf6_as_external_lsa
*) (lsa_header
+ 1);
591 prefix
.family
= AF_INET6
;
592 prefix
.prefixlen
= as_external_lsa
->ospf6_prefix
.prefix_length
;
593 ospf6_prefix_in6_addr (&as_external_lsa
->ospf6_prefix
, &prefix
.prefix
);
594 prefix2str ((struct prefix
*) &prefix
, pstring
, sizeof (pstring
));
595 memset (opt_capability
, 0, sizeof (opt_capability
));
597 if (lsa_header
->advrtr
== ospf6
->router_id
)
599 if (IS_OSPF6_DUMP_ROUTE
)
600 zlog_info ("ROUTE: LSA is Self-originated: %s", lsa
->str
);
604 if (ospf6_lsa_is_maxage (lsa
))
606 if (IS_OSPF6_DUMP_ROUTE
)
607 zlog_info ("ROUTE: %s: MaxAge", lsa
->str
);
609 /* If we have the route derived from this LSA, delete the route */
610 node
= route_node_lookup (ospf6
->route_table
, (struct prefix
*) &prefix
);
611 if (node
&& node
->info
)
613 ri
= (struct ospf6_route_info
*) node
->info
;
614 if (ri
->origin_id
== lsa_header
->ls_id
&&
615 ri
->origin_adv_router
== lsa_header
->advrtr
)
616 ospf6_route_delete ((struct prefix
*) &prefix
, ospf6
->route_table
);
621 /* test ASBR entry */
622 ri
= ospf6_route_asbr_entry (lsa_header
->advrtr
, ospf6
);
625 if (IS_OSPF6_DUMP_ROUTE
)
626 zlog_info ("ROUTE: %s: no ASBR", lsa
->str
);
632 /* Forwarding Address test */
633 if (as_external_lsa
->ase_bits
& ASE_LSA_BIT_F
)
635 if (IS_OSPF6_DUMP_ROUTE
)
636 zlog_info ("ROUTE: Forwarding flag specified");
638 forwarding_address
= (struct in6_addr
*)
639 OSPF6_NEXT_PREFIX (&as_external_lsa
->ospf6_prefix
);
640 memcpy (&forwarding
.prefix
, forwarding_address
,
641 sizeof (struct in6_addr
));
642 forwarding
.family
= AF_INET6
;
643 forwarding
.prefixlen
= 128;
645 /* test if forwarding address is on the routing table */
646 node
= route_node_match (ospf6
->route_table
,
647 (struct prefix
*) &forwarding
);
648 if (! node
|| ! node
->info
)
650 if (IS_OSPF6_DUMP_ROUTE
)
651 zlog_info ("ROUTE: Fowarding-address not on the table");
655 /* overwrite asbr internal cost */
656 ri
= (struct ospf6_route_info
*) node
->info
;
660 if (as_external_lsa
->ase_bits
& ASE_LSA_BIT_E
)
663 cost2
= ntohs (as_external_lsa
->ase_metric
);
664 path_type
= OSPF6_ROUTE_PATH_TYPE_EXTERNAL2
;
669 cost1
+= ntohs (as_external_lsa
->ase_metric
);
670 path_type
= OSPF6_ROUTE_PATH_TYPE_EXTERNAL1
;
673 ospf6_route_create ((struct prefix
*) &prefix
, pstring
,
674 opt_capability
, 0, ri
->area_id
,
675 path_type
, cost1
, cost2
,
676 lsa_header
->ls_id
, lsa_header
->advrtr
,
677 ri
->nexthop_list
, ospf6
->route_table
);
681 ospf6_route_calculation_external (struct ospf6
*o6
)
683 struct ospf6_lsdb_node
*node
;
685 for (node
= ospf6_lsdb_head (o6
->lsdb
); node
; node
= ospf6_lsdb_next (node
))
687 if (node
->lsa
->header
->type
!= htons (OSPF6_LSA_TYPE_AS_EXTERNAL
))
690 ospf6_route_external (node
->lsa
);
695 ospf6_route_invalidate ()
697 struct route_node
*node
;
698 struct ospf6_route_info
*route_info
;
700 if (IS_OSPF6_DUMP_ROUTE
)
701 zlog_info ("ROUTE: Invalidate routing table");
703 for (node
= route_top (ospf6
->route_table
); node
; node
= route_next (node
))
707 route_info
= (struct ospf6_route_info
*) node
->info
;
708 UNSET_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
);
713 ospf6_route_validate ()
715 struct route_node
*node
;
716 struct ospf6_route_info
*route_info
;
717 char prefix_string
[64];
719 if (IS_OSPF6_DUMP_ROUTE
)
720 zlog_info ("ROUTE: Validate routing table");
722 for (node
= route_top (ospf6
->route_table
); node
; node
= route_next (node
))
726 route_info
= (struct ospf6_route_info
*) node
->info
;
728 prefix2str (&node
->p
, prefix_string
, sizeof (prefix_string
));
731 zlog_info ("ROUTE: DEBUG: update route: %s %s %s",
732 (CHECK_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ZEBRA_SYNC
) ?
733 "sync'ed": "nosync"),
734 (CHECK_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
) ?
735 "active": "inactive"), prefix_string
);
738 ospf6_zebra_route_update ((struct prefix_ipv6
*) &node
->p
,
741 if (! CHECK_FLAG (route_info
->flag
, OSPF6_ROUTE_FLAG_ACTIVE
))
742 ospf6_route_delete (&node
->p
, ospf6
->route_table
);
747 ospf6_route_calculation_new ()
750 struct ospf6_area
*o6a
;
753 ospf6
->stat_route_calculation_execed
++;
755 /* invalidate current routing table */
756 ospf6_route_invalidate ();
758 /* Intra-Area Routes */
759 for (node
= listhead (ospf6
->area_list
); node
; nextnode (node
))
761 o6a
= (struct ospf6_area
*) getdata (node
);
762 ospf6_route_calculation_intra_area (o6a
);
765 /* Inter-Area Routes */
766 if (listcount (ospf6
->area_list
) == 1)
768 o6a
= (struct ospf6_area
*) getdata (listhead (ospf6
->area_list
));
769 ospf6_route_calculation_inter_area (o6a
);
773 /* calculate Inter-Area routes for backbone */
774 o6a
= ospf6_area_lookup (htonl (0), ospf6
);
775 ospf6_route_calculation_inter_area (o6a
);
778 /* Better Inter-Area Routes if this is Transit Area */
779 for (node
= listhead (ospf6
->area_list
); node
; nextnode (node
))
781 o6a
= (struct ospf6_area
*) getdata (node
);
782 if (ospf6_area_is_transit (o6a
))
783 ospf6_route_calculation_inter_area (o6a
);
786 /* External Routes associated with this area */
787 ospf6_route_calculation_external (ospf6
);
789 /* update zebra routing table */
790 ospf6_route_validate ();
794 ospf6_route_calculation_thread (struct thread
*t
)
796 ospf6_route_calculation_new ();
797 ospf6
->t_route_calculation
= (struct thread
*) NULL
;
802 ospf6_route_calculation_schedule ()
804 if (ospf6
->t_route_calculation
)
807 ospf6
->t_route_calculation
=
808 thread_add_event (master
, ospf6_route_calculation_thread
, NULL
, 0);
812 ospf6_route_external_incremental (struct ospf6_lsa
*lsa
)
814 struct ospf6_lsa_header
*lsa_header
;
815 lsa_header
= (struct ospf6_lsa_header
*) lsa
->lsa_hdr
;
817 if (lsa_header
->type
!= htons (OSPF6_LSA_TYPE_AS_EXTERNAL
))
820 ospf6_route_external (lsa
);
821 ospf6_route_validate ();
825 ospf6_route_path_type_string (u_char path_type
, char *buf
, int size
)
827 if (path_type
== OSPF6_ROUTE_PATH_TYPE_INTRA
)
828 snprintf (buf
, size
, "IA");
829 else if (path_type
== OSPF6_ROUTE_PATH_TYPE_INTER
)
830 snprintf (buf
, size
, "OA");
831 else if (path_type
== OSPF6_ROUTE_PATH_TYPE_EXTERNAL1
)
832 snprintf (buf
, size
, "E1");
833 else if (path_type
== OSPF6_ROUTE_PATH_TYPE_EXTERNAL2
)
834 snprintf (buf
, size
, "E2");
836 snprintf (buf
, size
, "%d", path_type
);
841 ospf6_route_statistics_show (struct vty
*vty
, struct route_table
*table
)
843 struct route_node
*node
;
844 struct ospf6_route_info
*info
;
845 u_int route_count
, intra_count
, inter_count
, e1_count
, e2_count
, ecmp_count
;
847 route_count
= intra_count
= inter_count
= e1_count
= e2_count
= ecmp_count
849 for (node
= route_top (table
); node
; node
= route_next (node
))
851 info
= (struct ospf6_route_info
*) node
->info
;
856 if (info
->path_type
== OSPF6_ROUTE_PATH_TYPE_INTRA
)
858 else if (info
->path_type
== OSPF6_ROUTE_PATH_TYPE_INTER
)
860 else if (info
->path_type
== OSPF6_ROUTE_PATH_TYPE_EXTERNAL1
)
862 else if (info
->path_type
== OSPF6_ROUTE_PATH_TYPE_EXTERNAL2
)
865 if (listcount (info
->nexthop_list
) > 1)
869 vty_out (vty
, " Current Route count: %d%s",
870 route_count
, VTY_NEWLINE
);
871 vty_out (vty
, " Intra: %d Inter: %d External: %d (Type1 %d/Type2 %d)%s",
872 intra_count
, inter_count
, e1_count
+ e2_count
,
873 e1_count
, e2_count
, VTY_NEWLINE
);
874 vty_out (vty
, " Equal-cost multi-path: %d%s",
875 ecmp_count
, VTY_NEWLINE
);
879 ospf6_route_entry_show (struct vty
*vty
, struct prefix_ipv6
*d
,
880 struct ospf6_route_info
*ri
)
883 struct ospf6_nexthop
*n
;
884 char buf
[64], dstring
[64], opt_string
[16], nstring
[64], ifname
[16];
885 char astring
[32], origin_string
[32], pstring
[4];
888 prefix2str ((struct prefix
*) d
, dstring
, sizeof (dstring
));
890 /* optional capability */
891 ospf6_opt_capability_string (ri
->opt_capability
, opt_string
,
892 sizeof (opt_string
));
895 inet_ntop (AF_INET
, &ri
->area_id
, astring
, sizeof (astring
));
898 ospf6_route_path_type_string (ri
->path_type
, pstring
, sizeof (pstring
));
900 /* Link state origin */
901 inet_ntop (AF_INET
, &ri
->origin_adv_router
, buf
, sizeof (buf
));
902 snprintf (origin_string
, sizeof (origin_string
),
903 "%s[%lu]", buf
, (unsigned long) ntohl (ri
->origin_id
));
905 for (node
= listhead (ri
->nexthop_list
); node
; nextnode (node
))
907 n
= (struct ospf6_nexthop
*) getdata (node
);
909 inet_ntop (AF_INET6
, &n
->ipaddr
, nstring
, sizeof (nstring
));
911 if (if_indextoname (n
->ifindex
, buf
))
912 snprintf (ifname
, sizeof (ifname
), "%s", buf
);
914 snprintf (ifname
, sizeof (ifname
), "%d", n
->ifindex
);
916 vty_out (vty
, "%c%2s %-43s %-9s %-8s %4d %-5d %-19s %-25s %4s%s",
917 (CHECK_FLAG (ri
->flag
, OSPF6_ROUTE_FLAG_ZEBRA_SYNC
) ? '*' : ' '),
918 pstring
, dstring
, opt_string
, astring
, ri
->cost
, ri
->cost_e2
,
919 origin_string
, nstring
, ifname
, VTY_NEWLINE
);
924 ospf6_route_table_show_new (struct vty
*vty
, struct route_table
*table
)
926 struct route_node
*node
;
927 struct ospf6_route_info
*info
;
929 vty_out (vty
, "%3s %-43s %-9s %-8s %4s %-5s %-19s %-25s %4s%s",
930 " ", "Destination", "Options", "Area", "Cost", "Type2",
931 "LS Origin", "Nexthop", "I/F", VTY_NEWLINE
);
933 for (node
= route_top (table
); node
; node
= route_next (node
))
935 info
= (struct ospf6_route_info
*) node
->info
;
938 ospf6_route_entry_show (vty
, (struct prefix_ipv6
*) &node
->p
, info
);
942 DEFUN (show_ipv6_route_ospf6_new
,
943 show_ipv6_route_ospf6_new_cmd
,
944 "show ipv6 route ospf6",
952 OSPF6_CMD_CHECK_RUNNING ();
954 ospf6_route_table_show_new (vty
, ospf6
->route_table
);
958 DEFUN (show_ipv6_route_ospf6_prefix
,
959 show_ipv6_route_ospf6_prefix_cmd
,
960 "show ipv6 route ospf6 X::X",
965 "match IPv6 prefix\n"
969 struct route_node
*node
;
970 struct ospf6_route_info
*info
;
973 OSPF6_CMD_CHECK_RUNNING ();
976 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &p
);
978 return CMD_ERR_NO_MATCH
;
980 node
= route_node_match (ospf6
->route_table
, &p
);
981 if (! node
|| ! node
->info
)
983 vty_out (vty
, "Route not found%s", VTY_NEWLINE
);
987 vty_out (vty
, "%3s %-43s %-9s %-8s %4s %-5s %-19s %-25s %4s%s",
988 " ", "Destination", "Options", "Area", "Cost", "Type2",
989 "LS Origin", "Nexthop", "I/F", VTY_NEWLINE
);
991 info
= (struct ospf6_route_info
*) node
->info
;
992 ospf6_route_entry_show (vty
, (struct prefix_ipv6
*) &node
->p
, info
);
999 install_element (VIEW_NODE
, &show_ipv6_route_ospf6_new_cmd
);
1000 install_element (VIEW_NODE
, &show_ipv6_route_ospf6_prefix_cmd
);
1001 install_element (ENABLE_NODE
, &show_ipv6_route_ospf6_new_cmd
);
1002 install_element (ENABLE_NODE
, &show_ipv6_route_ospf6_prefix_cmd
);