1/* 2 * OSPFv3 Top Level Data Structure 3 * Copyright (C) 1999 Yasuhiro Ohara 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * GNU Zebra is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Zebra; see the file COPYING. If not, write to the 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#include "log.h" 26#include "memory.h" 27#include "vty.h" 28#include "linklist.h" 29#include "prefix.h" 30#include "table.h" 31#include "thread.h" 32#include "command.h" 33 34#include "ospf6_hook.h" 35#include "ospf6_proto.h" 36#include "ospf6_prefix.h" 37#include "ospf6_lsa.h" 38#include "ospf6_lsdb.h" 39 40#include "ospf6_message.h" 41#include "ospf6_neighbor.h" 42#include "ospf6_interface.h" 43#include "ospf6_area.h" 44#include "ospf6_top.h" 45 46#include "ospf6_redistribute.h" 47#include "ospf6_route.h" 48#include "ospf6_zebra.h" 49 50#include "ospf6_nsm.h" 51#include "ospf6_asbr.h" 52#include "ospf6_abr.h" 53 54#define HEADER_DEPENDENCY 55#include "ospf6d.h" 56#undef HEADER_DEPENDENCY 57 58/* global ospf6d variable */ 59struct ospf6 *ospf6; 60 61static void 62ospf6_top_foreach_area (struct ospf6 *o6, void *arg, int val, 63 void (*func) (void *, int, void *)) 64{ 65 listnode node; 66 struct ospf6_area *o6a; 67 68 for (node = listhead (o6->area_list); node; nextnode (node)) 69 { 70 o6a = (struct ospf6_area *) getdata (node); 71 (*func) (arg, val, o6a); 72 } 73} 74 75static void 76ospf6_top_foreach_interface (struct ospf6 *o6, void *arg, int val, 77 void (*func) (void *, int, void *)) 78{ 79 listnode node; 80 struct ospf6_area *o6a; 81 82 for (node = listhead (o6->area_list); node; nextnode (node)) 83 { 84 o6a = (struct ospf6_area *) getdata (node); 85 (*o6a->foreach_if) (o6a, arg, val, func); 86 } 87} 88 89static void 90ospf6_top_foreach_neighbor (struct ospf6 *o6, void *arg, int val, 91 void (*func) (void *, int, void *)) 92{ 93 listnode node; 94 struct ospf6_area *o6a; 95 96 for (node = listhead (o6->area_list); node; nextnode (node)) 97 { 98 o6a = (struct ospf6_area *) getdata (node); 99 (*o6a->foreach_nei) (o6a, arg, val, func); 100 } 101} 102 103static int 104ospf6_top_maxage_remover (struct thread *t) 105{ 106 int count; 107 struct ospf6 *o6 = (struct ospf6 *) THREAD_ARG (t); 108 109 o6->maxage_remover = (struct thread *) NULL; 110 111 count = 0; 112 o6->foreach_nei (o6, &count, NBS_EXCHANGE, ospf6_count_state); 113 o6->foreach_nei (o6, &count, NBS_LOADING, ospf6_count_state); 114 if (count != 0) 115 return 0; 116 117 ospf6_lsdb_remove_maxage (o6->lsdb); 118 return 0; 119} 120 121void 122ospf6_top_schedule_maxage_remover (void *arg, int val, struct ospf6 *o6) 123{ 124 if (o6->maxage_remover != NULL) 125 return; 126 127 o6->maxage_remover = 128 thread_add_event (master, ospf6_top_maxage_remover, o6, 0); 129} 130 131void 132ospf6_show (struct vty *vty) 133{ 134 listnode n; 135 struct ospf6_area *area; 136 char id_string[32]; 137 unsigned long day, hour, min, sec; 138 struct timeval now, running; 139 140 /* process id, router id */ 141 inet_ntop (AF_INET, &ospf6->router_id, id_string, sizeof (id_string)); 142 vty_out (vty, " Routing Process (%lu) with ID %s%s", 143 ospf6->process_id, id_string, VTY_NEWLINE); 144 145 /* running time */ 146 gettimeofday (&now, (struct timezone *)NULL); 147 ospf6_timeval_sub (&now, &ospf6->starttime, &running); 148 ospf6_timeval_decode (&running, &day, &hour, &min, &sec, NULL, NULL); 149 vty_out (vty, " Running %ld days %ld hours %ld minutes %ld seconds%s", 150 day, hour, min, sec, VTY_NEWLINE); 151 152 vty_out (vty, " Supports only single TOS(TOS0) routes%s", VTY_NEWLINE); 153 154 /* Redistribute config */ 155 ospf6_redistribute_show_config (vty, ospf6); 156 157 /* LSAs */ 158 vty_out (vty, " Number of AS scoped LSAs is %u%s", 159 ospf6->lsdb->count, VTY_NEWLINE); 160 vty_out (vty, " Route calculation executed %d times%s", 161 ospf6->stat_route_calculation_execed, VTY_NEWLINE); 162 163 /* Route Statistics */ 164#if 0 165 ospf6_route_statistics_show (vty, ospf6->route_table); 166#endif 167 168 /* Areas */ 169 vty_out (vty, " Number of areas in this router is %u%s", 170 listcount (ospf6->area_list), VTY_NEWLINE); 171 for (n = listhead (ospf6->area_list); n; nextnode (n)) 172 { 173 area = (struct ospf6_area *) getdata (n); 174 ospf6_area_show (vty, area); 175 } 176} 177 178void 179ospf6_statistics_show (struct vty *vty, struct ospf6 *o6) 180{ 181 listnode node; 182 struct ospf6_area *o6a; 183 char running_time[128]; 184 struct timeval now, running; 185 186 gettimeofday (&now, (struct timezone *) NULL); 187 ospf6_timeval_sub (&now, &o6->starttime, &running); 188 ospf6_timeval_string (&running, running_time, sizeof (running_time)); 189 190 vty_out (vty, "Statistics of OSPF process %ld%s", 191 o6->process_id, VTY_NEWLINE); 192 vty_out (vty, " Running: %s%s", running_time, VTY_NEWLINE); 193 194#if 0 195 ospf6_route_statistics_show (vty, o6->route_table); 196#endif 197 198 for (node = listhead (o6->area_list); node; nextnode (node)) 199 { 200 o6a = (struct ospf6_area *) getdata (node); 201 ospf6_area_statistics_show (vty, o6a); 202 } 203} 204 205static struct ospf6 * 206ospf6_new () 207{ 208 struct ospf6 *new; 209 new = XMALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6)); 210 if (new) 211 memset (new, 0, sizeof (struct ospf6)); 212 return new; 213} 214 215void 216ospf6_free (struct ospf6 *ospf6) 217{ 218 XFREE (MTYPE_OSPF6_TOP, ospf6); 219} 220 221void 222ospf6_top_topology_add (struct ospf6_route_req *request) 223{ 224 assert (request->route.type == OSPF6_DEST_TYPE_ROUTER); 225 if (CHECK_FLAG (request->path.router_bits, OSPF6_ROUTER_LSA_BIT_E)) 226 ospf6_asbr_asbr_entry_add (request); 227} 228 229void 230ospf6_top_topology_remove (struct ospf6_route_req *request) 231{ 232 assert (request->route.type == OSPF6_DEST_TYPE_ROUTER); 233 if (CHECK_FLAG (request->path.router_bits, OSPF6_ROUTER_LSA_BIT_E)) 234 ospf6_asbr_asbr_entry_remove (request); 235} 236 237struct ospf6 * 238ospf6_create (unsigned long process_id) 239{ 240 struct ospf6 *o6; 241 char namebuf[64]; 242 243 o6 = ospf6_new (); 244 245 /* initialize */ 246 gettimeofday (&o6->starttime, (struct timezone *)NULL); 247 o6->process_id = process_id; 248 o6->version = OSPF6_VERSION; 249 o6->area_list = list_new (); 250 251 o6->lsdb = ospf6_lsdb_create (); 252 253 /* route table init */ 254 ospf6_redistribute_init (o6); 255 256 o6->foreach_area = ospf6_top_foreach_area; 257 o6->foreach_if = ospf6_top_foreach_interface; 258 o6->foreach_nei = ospf6_top_foreach_neighbor; 259 260 snprintf (namebuf, sizeof (namebuf), "InterTopology table"); 261 o6->topology_table = ospf6_route_table_create (namebuf); 262 ospf6_route_hook_register (ospf6_top_topology_add, 263 ospf6_top_topology_add, 264 ospf6_top_topology_remove, 265 o6->topology_table); 266 267 snprintf (namebuf, sizeof (namebuf), "External table"); 268 o6->external_table = ospf6_route_table_create (namebuf); 269 ospf6_route_hook_register (ospf6_asbr_external_route_add, 270 ospf6_asbr_external_route_add, 271 ospf6_asbr_external_route_remove, 272 o6->external_table); 273 274 snprintf (namebuf, sizeof (namebuf), "Top route table"); 275 o6->route_table = ospf6_route_table_create (namebuf); 276 ospf6_route_hook_register (ospf6_zebra_route_update_add, 277 ospf6_zebra_route_update_add, 278 ospf6_zebra_route_update_remove, 279 o6->route_table); 280 ospf6_route_hook_register (ospf6_abr_route_add, 281 ospf6_abr_route_add, 282 ospf6_abr_route_remove, 283 o6->route_table); 284 285 return o6; 286} 287 288void 289ospf6_delete (struct ospf6 *ospf6) 290{ 291 ospf6_route_remove_all (ospf6->route_table); 292 ospf6_free (ospf6); 293} 294 295struct ospf6 * 296ospf6_start () 297{ 298 if (ospf6) 299 return ospf6; 300 301 ospf6 = ospf6_create (0); 302 return ospf6; 303} 304 305void 306ospf6_stop () 307{ 308 if (!ospf6) 309 return; 310 311 ospf6_delete (ospf6); 312 ospf6 = NULL; 313} 314 315int 316ospf6_is_asbr (struct ospf6 *o6) 317{ 318 int i = 0; 319 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_SYSTEM); 320 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_CONNECT); 321 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_STATIC); 322 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_KERNEL); 323 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_RIPNG); 324 i |= ospf6_zebra_is_redistribute (ZEBRA_ROUTE_BGP); 325 return (i); 326} 327 328DEFUN (show_ipv6_ospf6_route, 329 show_ipv6_ospf6_route_cmd, 330 "show ipv6 ospf6 route", 331 SHOW_STR 332 IP6_STR 333 OSPF6_STR 334 "Routing table\n" 335 ) 336{ 337 OSPF6_CMD_CHECK_RUNNING (); 338 return ospf6_route_table_show (vty, argc, argv, ospf6->route_table); 339} 340 341ALIAS (show_ipv6_ospf6_route, 342 show_ipv6_ospf6_route_prefix_cmd, 343 "show ipv6 ospf6 route (X::X|detail)", 344 SHOW_STR 345 IP6_STR 346 OSPF6_STR 347 "Routing table\n" 348 "match IPv6 prefix\n" 349 ) 350 351DEFUN (show_ipv6_ospf6_topology, 352 show_ipv6_ospf6_topology_cmd, 353 "show ipv6 ospf6 topology", 354 SHOW_STR 355 IP6_STR 356 OSPF6_STR 357 "Inter Area topology information\n" 358 ) 359{ 360 OSPF6_CMD_CHECK_RUNNING (); 361 return ospf6_route_table_show (vty, argc, argv, ospf6->topology_table); 362} 363 364ALIAS (show_ipv6_ospf6_topology, 365 show_ipv6_ospf6_topology_router_cmd, 366 "show ipv6 ospf6 topology (A.B.C.D|<0-4294967295>|detail)", 367 SHOW_STR 368 IP6_STR 369 OSPF6_STR 370 "Inter Area topology information\n" 371 OSPF6_ROUTER_ID_STR 372 OSPF6_ROUTER_ID_STR 373 "Detailed information\n" 374 ) 375 376ALIAS (show_ipv6_ospf6_topology, 377 show_ipv6_ospf6_topology_router_lsid_cmd, 378 "show ipv6 ospf6 topology (A.B.C.D|<0-4294967295>) (A.B.C.D|<0-4294967295>)", 379 SHOW_STR 380 IP6_STR 381 OSPF6_STR 382 "Inter Area topology information\n" 383 OSPF6_ROUTER_ID_STR 384 OSPF6_ROUTER_ID_STR 385 OSPF6_LS_ID_STR 386 OSPF6_LS_ID_STR 387 ) 388 389void 390ospf6_top_init () 391{ 392 install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd); 393 install_element (VIEW_NODE, &show_ipv6_ospf6_route_prefix_cmd); 394 install_element (VIEW_NODE, &show_ipv6_ospf6_topology_cmd); 395 install_element (VIEW_NODE, &show_ipv6_ospf6_topology_router_cmd); 396 install_element (VIEW_NODE, &show_ipv6_ospf6_topology_router_lsid_cmd); 397 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd); 398 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_prefix_cmd); 399 install_element (ENABLE_NODE, &show_ipv6_ospf6_topology_cmd); 400 install_element (ENABLE_NODE, &show_ipv6_ospf6_topology_router_cmd); 401 install_element (ENABLE_NODE, &show_ipv6_ospf6_topology_router_lsid_cmd); 402} 403 404