]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
SVN revision 907 from Zebra cvs repository.
[mirror_frr.git] / ospf6d / ospf6_top.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 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 "memory.h"
26#include "vty.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "table.h"
30#include "thread.h"
31#include "command.h"
32
718e3744 33#include "ospf6_proto.h"
508e53e2 34#include "ospf6_message.h"
718e3744 35#include "ospf6_lsa.h"
36#include "ospf6_lsdb.h"
718e3744 37#include "ospf6_route.h"
38#include "ospf6_zebra.h"
39
508e53e2 40#include "ospf6_top.h"
41#include "ospf6_area.h"
42#include "ospf6_interface.h"
43#include "ospf6_neighbor.h"
718e3744 44
508e53e2 45#include "ospf6_asbr.h"
049207c3 46#include "ospf6_abr.h"
47#include "ospf6d.h"
718e3744 48
49/* global ospf6d variable */
50struct ospf6 *ospf6;
51
508e53e2 52void
53ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
718e3744 54{
508e53e2 55 switch (ntohs (lsa->header->type))
718e3744 56 {
508e53e2 57 case OSPF6_LSTYPE_AS_EXTERNAL:
58 ospf6_asbr_lsa_add (lsa);
59 break;
60
61 default:
62 if (IS_OSPF6_DEBUG_LSA (RECV))
63 zlog_info ("Unknown LSA in AS-scoped lsdb");
64 break;
718e3744 65 }
66}
67
508e53e2 68void
69ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
718e3744 70{
508e53e2 71 switch (ntohs (lsa->header->type))
718e3744 72 {
508e53e2 73 case OSPF6_LSTYPE_AS_EXTERNAL:
74 ospf6_asbr_lsa_remove (lsa);
75 break;
76
77 default:
78 if (IS_OSPF6_DEBUG_LSA (RECV))
79 zlog_info ("Unknown LSA in AS-scoped lsdb");
80 break;
718e3744 81 }
82}
83
049207c3 84void
85ospf6_top_route_hook_add (struct ospf6_route *route)
86{
87 ospf6_abr_originate_prefix (route, ospf6);
88 ospf6_zebra_route_update_add (route);
89}
90
91void
92ospf6_top_route_hook_remove (struct ospf6_route *route)
93{
94 ospf6_abr_originate_prefix (route, ospf6);
95 ospf6_zebra_route_update_remove (route);
96}
97
508e53e2 98struct ospf6 *
99ospf6_create ()
718e3744 100{
508e53e2 101 struct ospf6 *o;
718e3744 102
508e53e2 103 o = XMALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6));
104 memset (o, 0, sizeof (struct ospf6));
718e3744 105
508e53e2 106 /* initialize */
107 gettimeofday (&o->starttime, (struct timezone *) NULL);
108 o->area_list = list_new ();
109 o->area_list->cmp = ospf6_area_cmp;
110 o->lsdb = ospf6_lsdb_create ();
111 o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
112 o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
718e3744 113
508e53e2 114 o->route_table = ospf6_route_table_create ();
049207c3 115 o->route_table->hook_add = ospf6_top_route_hook_add;
116 o->route_table->hook_remove = ospf6_top_route_hook_remove;
718e3744 117
508e53e2 118 o->asbr_table = ospf6_route_table_create ();
119 o->asbr_table->hook_add = ospf6_asbr_lsentry_add;
120 o->asbr_table->hook_remove = ospf6_asbr_lsentry_remove;
718e3744 121
049207c3 122 o->brouter_table = ospf6_route_table_create ();
123
508e53e2 124 o->external_table = ospf6_route_table_create ();
125 o->external_id_table = route_table_init ();
718e3744 126
508e53e2 127 return o;
718e3744 128}
129
130void
508e53e2 131ospf6_delete (struct ospf6 *o)
718e3744 132{
508e53e2 133 listnode i;
134 struct ospf6_area *oa;
718e3744 135
508e53e2 136 for (i = listhead (o->area_list); i; nextnode (i))
137 {
138 oa = (struct ospf6_area *) getdata (i);
139 ospf6_area_delete (oa);
140 }
718e3744 141
508e53e2 142 ospf6_lsdb_delete (o->lsdb);
718e3744 143
508e53e2 144 ospf6_route_table_delete (o->route_table);
145 ospf6_route_table_delete (o->asbr_table);
049207c3 146 ospf6_route_table_delete (o->brouter_table);
718e3744 147
508e53e2 148 ospf6_route_table_delete (o->external_table);
149 route_table_finish (o->external_id_table);
718e3744 150
508e53e2 151 XFREE (MTYPE_OSPF6_TOP, o);
152}
718e3744 153
508e53e2 154void
155ospf6_enable (struct ospf6 *o)
156{
157 listnode i;
158 struct ospf6_area *oa;
718e3744 159
508e53e2 160 if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
718e3744 161 {
508e53e2 162 UNSET_FLAG (o->flag, OSPF6_DISABLED);
163 for (i = listhead (o->area_list); i; nextnode (i))
164 {
165 oa = (struct ospf6_area *) getdata (i);
166 ospf6_area_enable (oa);
167 }
718e3744 168 }
169}
170
171void
508e53e2 172ospf6_disable (struct ospf6 *o)
718e3744 173{
508e53e2 174 listnode i;
175 struct ospf6_area *oa;
718e3744 176
508e53e2 177 if (! CHECK_FLAG (o->flag, OSPF6_DISABLED))
178 {
179 SET_FLAG (o->flag, OSPF6_DISABLED);
180 for (i = listhead (o->area_list); i; nextnode (i))
181 {
182 oa = (struct ospf6_area *) getdata (i);
183 ospf6_area_disable (oa);
184 }
185
186 ospf6_lsdb_remove_all (o->lsdb);
187 ospf6_route_remove_all (o->route_table);
188 ospf6_route_remove_all (o->asbr_table);
189 }
190}
718e3744 191
508e53e2 192int
193ospf6_maxage_remover (struct thread *thread)
194{
195 struct ospf6 *o = (struct ospf6 *) THREAD_ARG (thread);
196 struct ospf6_area *oa;
197 struct ospf6_interface *oi;
198 struct ospf6_neighbor *on;
199 listnode i, j, k;
718e3744 200
508e53e2 201 o->maxage_remover = (struct thread *) NULL;
202 if (IS_OSPF6_DEBUG_LSA (TIMER))
203 zlog_info ("Maxage Remover");
718e3744 204
508e53e2 205 for (i = listhead (o->area_list); i; nextnode (i))
718e3744 206 {
508e53e2 207 oa = (struct ospf6_area *) getdata (i);
208 for (j = listhead (oa->if_list); j; nextnode (j))
209 {
210 oi = (struct ospf6_interface *) getdata (j);
211 for (k = listhead (oi->neighbor_list); k; nextnode (k))
212 {
213 on = (struct ospf6_neighbor *) getdata (k);
214 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
215 on->state != OSPF6_NEIGHBOR_LOADING)
216 continue;
217
218 if (IS_OSPF6_DEBUG_LSA (TIMER))
219 zlog_info ("Maxage Remover End: %s exchange or loading",
220 on->name);
221 return 0;
222 }
223 }
718e3744 224 }
718e3744 225
508e53e2 226 for (i = listhead (o->area_list); i; nextnode (i))
227 {
228 oa = (struct ospf6_area *) getdata (i);
229 for (j = listhead (oa->if_list); j; nextnode (j))
230 {
231 oi = (struct ospf6_interface *) getdata (j);
232 OSPF6_LSDB_MAXAGE_REMOVER (oi->lsdb);
233 }
234 OSPF6_LSDB_MAXAGE_REMOVER (oa->lsdb);
235 }
236 OSPF6_LSDB_MAXAGE_REMOVER (o->lsdb);
237
238 if (IS_OSPF6_DEBUG_LSA (TIMER))
239 zlog_info ("Maxage Remover End");
240
241 return 0;
718e3744 242}
243
244void
508e53e2 245ospf6_maxage_remove (struct ospf6 *o)
718e3744 246{
508e53e2 247 if (o && ! o->maxage_remover)
248 o->maxage_remover = thread_add_event (master, ospf6_maxage_remover, o, 0);
718e3744 249}
250
508e53e2 251/* start ospf6 */
252DEFUN (router_ospf6,
253 router_ospf6_cmd,
254 "router ospf6",
255 ROUTER_STR
256 OSPF6_STR)
718e3744 257{
508e53e2 258 if (ospf6 == NULL)
259 ospf6 = ospf6_create ();
260 if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
261 ospf6_enable (ospf6);
262
263 /* set current ospf point. */
264 vty->node = OSPF6_NODE;
265 vty->index = ospf6;
266
267 return CMD_SUCCESS;
718e3744 268}
269
508e53e2 270/* stop ospf6 */
271DEFUN (no_router_ospf6,
272 no_router_ospf6_cmd,
273 "no router ospf6",
274 NO_STR
275 OSPF6_ROUTER_STR)
718e3744 276{
508e53e2 277 if (ospf6 == NULL || CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
049207c3 278 vty_out (vty, "OSPFv3 is not running%s", VNL);
508e53e2 279 else
280 ospf6_disable (ospf6);
281
282 /* return to config node . */
283 vty->node = CONFIG_NODE;
284 vty->index = NULL;
285
286 return CMD_SUCCESS;
718e3744 287}
288
508e53e2 289/* change Router_ID commands. */
290DEFUN (ospf6_router_id,
291 ospf6_router_id_cmd,
292 "router-id A.B.C.D",
293 "Configure OSPF Router-ID\n"
294 V4NOTATION_STR)
718e3744 295{
508e53e2 296 int ret;
297 u_int32_t router_id;
298 struct ospf6 *o;
718e3744 299
508e53e2 300 o = (struct ospf6 *) vty->index;
718e3744 301
508e53e2 302 ret = inet_pton (AF_INET, argv[0], &router_id);
303 if (ret == 0)
304 {
049207c3 305 vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
508e53e2 306 return CMD_SUCCESS;
307 }
308
309 o->router_id = router_id;
310 return CMD_SUCCESS;
718e3744 311}
312
508e53e2 313DEFUN (ospf6_interface_area,
314 ospf6_interface_area_cmd,
315 "interface IFNAME area A.B.C.D",
316 "Enable routing on an IPv6 interface\n"
317 IFNAME_STR
318 "Specify the OSPF6 area ID\n"
319 "OSPF6 area ID in IPv4 address notation\n"
320 )
718e3744 321{
508e53e2 322 struct ospf6 *o;
323 struct ospf6_area *oa;
324 struct ospf6_interface *oi;
325 struct interface *ifp;
326 u_int32_t area_id;
327
328 o = (struct ospf6 *) vty->index;
329
330 /* find/create ospf6 interface */
331 ifp = if_get_by_name (argv[0]);
332 oi = (struct ospf6_interface *) ifp->info;
333 if (oi == NULL)
334 oi = ospf6_interface_create (ifp);
335 if (oi->area)
336 {
337 vty_out (vty, "%s already attached to Area %s%s",
049207c3 338 oi->interface->name, oi->area->name, VNL);
508e53e2 339 return CMD_SUCCESS;
340 }
341
342 /* parse Area-ID */
343 if (inet_pton (AF_INET, argv[1], &area_id) != 1)
344 {
049207c3 345 vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
508e53e2 346 return CMD_SUCCESS;
347 }
e26bbeba 348
508e53e2 349 /* find/create ospf6 area */
350 oa = ospf6_area_lookup (area_id, o);
351 if (oa == NULL)
352 oa = ospf6_area_create (area_id, o);
353
354 /* attach interface to area */
355 listnode_add (oa->if_list, oi); /* sort ?? */
356 oi->area = oa;
357
358 /* start up */
359 thread_add_event (master, interface_up, oi, 0);
360 return CMD_SUCCESS;
718e3744 361}
362
508e53e2 363DEFUN (no_ospf6_interface_area,
364 no_ospf6_interface_area_cmd,
365 "no interface IFNAME area A.B.C.D",
366 NO_STR
367 "Disable routing on an IPv6 interface\n"
368 IFNAME_STR
369 "Specify the OSPF6 area ID\n"
370 "OSPF6 area ID in IPv4 address notation\n"
371 )
718e3744 372{
508e53e2 373 struct ospf6 *o;
374 struct ospf6_interface *oi;
375 struct interface *ifp;
376 u_int32_t area_id;
718e3744 377
508e53e2 378 o = (struct ospf6 *) vty->index;
379
380 ifp = if_lookup_by_name (argv[0]);
381 if (ifp == NULL)
382 {
049207c3 383 vty_out (vty, "No such interface %s%s", argv[0], VNL);
508e53e2 384 return CMD_SUCCESS;
385 }
386
387 oi = (struct ospf6_interface *) ifp->info;
388 if (oi == NULL)
389 {
049207c3 390 vty_out (vty, "Interface %s not enabled%s", ifp->name, VNL);
508e53e2 391 return CMD_SUCCESS;
392 }
393
394 /* parse Area-ID */
395 if (inet_pton (AF_INET, argv[1], &area_id) != 1)
396 {
049207c3 397 vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
508e53e2 398 return CMD_SUCCESS;
399 }
400
401 if (oi->area->area_id != area_id)
402 {
403 vty_out (vty, "Wrong Area-ID: %s is attached to area %s%s",
049207c3 404 oi->interface->name, oi->area->name, VNL);
508e53e2 405 return CMD_SUCCESS;
406 }
407
408 thread_execute (master, interface_down, oi, 0);
409
410 listnode_delete (oi->area->if_list, oi);
411 oi->area = (struct ospf6_area *) NULL;
412
413 return CMD_SUCCESS;
718e3744 414}
415
416void
508e53e2 417ospf6_show (struct vty *vty, struct ospf6 *o)
718e3744 418{
508e53e2 419 listnode n;
420 struct ospf6_area *oa;
421 char router_id[16], duration[32];
422 struct timeval now, running;
423
424 /* process id, router id */
425 inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id));
426 vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s%s",
049207c3 427 router_id, VNL);
508e53e2 428
429 /* running time */
430 gettimeofday (&now, (struct timezone *)NULL);
431 timersub (&now, &o->starttime, &running);
432 timerstring (&running, duration, sizeof (duration));
049207c3 433 vty_out (vty, " Running %s%s", duration, VNL);
508e53e2 434
435 /* Redistribute configuration */
436 /* XXX */
437
438 /* LSAs */
439 vty_out (vty, " Number of AS scoped LSAs is %u%s",
049207c3 440 o->lsdb->count, VNL);
718e3744 441
508e53e2 442 /* Areas */
443 vty_out (vty, " Number of areas in this router is %u%s",
049207c3 444 listcount (o->area_list), VNL);
508e53e2 445 for (n = listhead (o->area_list); n; nextnode (n))
446 {
447 oa = (struct ospf6_area *) getdata (n);
448 ospf6_area_show (vty, oa);
449 }
718e3744 450}
451
508e53e2 452/* show top level structures */
453DEFUN (show_ipv6_ospf6,
454 show_ipv6_ospf6_cmd,
455 "show ipv6 ospf6",
456 SHOW_STR
457 IP6_STR
458 OSPF6_STR)
718e3744 459{
508e53e2 460 OSPF6_CMD_CHECK_RUNNING ();
461
462 ospf6_show (vty, ospf6);
463 return CMD_SUCCESS;
718e3744 464}
465
466DEFUN (show_ipv6_ospf6_route,
467 show_ipv6_ospf6_route_cmd,
468 "show ipv6 ospf6 route",
469 SHOW_STR
470 IP6_STR
471 OSPF6_STR
508e53e2 472 ROUTE_STR
718e3744 473 )
474{
508e53e2 475 ospf6_route_table_show (vty, argc, argv, ospf6->route_table);
476 return CMD_SUCCESS;
718e3744 477}
478
479ALIAS (show_ipv6_ospf6_route,
508e53e2 480 show_ipv6_ospf6_route_detail_cmd,
481 "show ipv6 ospf6 route (X::X|X::X/M|detail|summary)",
718e3744 482 SHOW_STR
483 IP6_STR
484 OSPF6_STR
508e53e2 485 ROUTE_STR
486 "Specify IPv6 address\n"
487 "Specify IPv6 prefix\n"
488 "Detailed information\n"
489 "Summary of route table\n"
490 );
718e3744 491
508e53e2 492DEFUN (show_ipv6_ospf6_route_match,
493 show_ipv6_ospf6_route_match_cmd,
494 "show ipv6 ospf6 route X::X/M match",
718e3744 495 SHOW_STR
496 IP6_STR
497 OSPF6_STR
508e53e2 498 ROUTE_STR
499 "Specify IPv6 prefix\n"
500 "Display routes which match the specified route\n"
718e3744 501 )
502{
508e53e2 503 char *sargv[CMD_ARGC_MAX];
504 int i, sargc;
505
506 /* copy argv to sargv and then append "match" */
507 for (i = 0; i < argc; i++)
508 sargv[i] = argv[i];
509 sargc = argc;
510 sargv[sargc++] = "match";
511 sargv[sargc] = NULL;
512
513 ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
514 return CMD_SUCCESS;
718e3744 515}
516
508e53e2 517DEFUN (show_ipv6_ospf6_route_match_detail,
518 show_ipv6_ospf6_route_match_detail_cmd,
519 "show ipv6 ospf6 route X::X/M match detail",
718e3744 520 SHOW_STR
521 IP6_STR
522 OSPF6_STR
508e53e2 523 ROUTE_STR
524 "Specify IPv6 prefix\n"
525 "Display routes which match the specified route\n"
718e3744 526 "Detailed information\n"
527 )
508e53e2 528{
529 char *sargv[CMD_ARGC_MAX];
530 int i, sargc;
531
532 /* copy argv to sargv and then append "match" and "detail" */
533 for (i = 0; i < argc; i++)
534 sargv[i] = argv[i];
535 sargc = argc;
536 sargv[sargc++] = "match";
537 sargv[sargc++] = "detail";
538 sargv[sargc] = NULL;
539
540 ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
541 return CMD_SUCCESS;
542}
718e3744 543
718e3744 544
508e53e2 545/* OSPF configuration write function. */
546int
547config_write_ospf6 (struct vty *vty)
548{
549 char router_id[16];
550 listnode j, k;
551 struct ospf6_area *oa;
552 struct ospf6_interface *oi;
553
554 /* OSPFv6 configuration. */
555 if (ospf6 == NULL)
556 return CMD_SUCCESS;
557 if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
558 return CMD_SUCCESS;
559
560 inet_ntop (AF_INET, &ospf6->router_id, router_id, sizeof (router_id));
049207c3 561 vty_out (vty, "router ospf6%s", VNL);
562 vty_out (vty, " router-id %s%s", router_id, VNL);
508e53e2 563
564 ospf6_redistribute_config_write (vty);
565
566 for (j = listhead (ospf6->area_list); j; nextnode (j))
567 {
568 oa = (struct ospf6_area *) getdata (j);
569 for (k = listhead (oa->if_list); k; nextnode (k))
570 {
571 oi = (struct ospf6_interface *) getdata (k);
572 vty_out (vty, " interface %s area %s%s",
049207c3 573 oi->interface->name, oa->name, VNL);
508e53e2 574 }
575 }
049207c3 576 vty_out (vty, "!%s", VNL);
508e53e2 577 return 0;
578}
579
580/* OSPF6 node structure. */
581struct cmd_node ospf6_node =
582{
583 OSPF6_NODE,
584 "%s(config-ospf6)# ",
585};
586
587/* Install ospf related commands. */
718e3744 588void
589ospf6_top_init ()
590{
508e53e2 591 /* Install ospf6 top node. */
592 install_node (&ospf6_node, config_write_ospf6);
593
594 install_element (VIEW_NODE, &show_ipv6_ospf6_cmd);
595 install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd);
596 install_element (CONFIG_NODE, &router_ospf6_cmd);
597
718e3744 598 install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
508e53e2 599 install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
600 install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
601 install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
718e3744 602 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd);
508e53e2 603 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_detail_cmd);
604 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd);
605 install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
606
607 install_default (OSPF6_NODE);
608 install_element (OSPF6_NODE, &ospf6_router_id_cmd);
609 install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
610 install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
611 install_element (OSPF6_NODE, &no_router_ospf6_cmd);
718e3744 612}
613
508e53e2 614