2 * Copyright (C) 2003 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.
33 #include "ospf6_proto.h"
34 #include "ospf6_message.h"
35 #include "ospf6_lsa.h"
36 #include "ospf6_lsdb.h"
37 #include "ospf6_route.h"
38 #include "ospf6_zebra.h"
40 #include "ospf6_top.h"
41 #include "ospf6_area.h"
42 #include "ospf6_interface.h"
43 #include "ospf6_neighbor.h"
45 #include "ospf6_flood.h"
46 #include "ospf6_asbr.h"
47 #include "ospf6_abr.h"
48 #include "ospf6_intra.h"
51 /* global ospf6d variable */
55 ospf6_top_lsdb_hook_add (struct ospf6_lsa
*lsa
)
57 switch (ntohs (lsa
->header
->type
))
59 case OSPF6_LSTYPE_AS_EXTERNAL
:
60 ospf6_asbr_lsa_add (lsa
);
69 ospf6_top_lsdb_hook_remove (struct ospf6_lsa
*lsa
)
71 switch (ntohs (lsa
->header
->type
))
73 case OSPF6_LSTYPE_AS_EXTERNAL
:
74 ospf6_asbr_lsa_remove (lsa
);
83 ospf6_top_route_hook_add (struct ospf6_route
*route
)
85 ospf6_abr_originate_summary (route
);
86 ospf6_zebra_route_update_add (route
);
90 ospf6_top_route_hook_remove (struct ospf6_route
*route
)
92 ospf6_abr_originate_summary (route
);
93 ospf6_zebra_route_update_remove (route
);
97 ospf6_top_brouter_hook_add (struct ospf6_route
*route
)
99 ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route
->prefix
));
100 ospf6_asbr_lsentry_add (route
);
101 ospf6_abr_originate_summary (route
);
105 ospf6_top_brouter_hook_remove (struct ospf6_route
*route
)
107 ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route
->prefix
));
108 ospf6_asbr_lsentry_remove (route
);
109 ospf6_abr_originate_summary (route
);
112 static struct ospf6
*
117 o
= XCALLOC (MTYPE_OSPF6_TOP
, sizeof (struct ospf6
));
120 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &o
->starttime
);
121 o
->area_list
= list_new ();
122 o
->area_list
->cmp
= ospf6_area_cmp
;
123 o
->lsdb
= ospf6_lsdb_create (o
);
124 o
->lsdb_self
= ospf6_lsdb_create (o
);
125 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
126 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
128 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, ROUTES
);
129 o
->route_table
->scope
= o
;
130 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
131 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
133 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, BORDER_ROUTERS
);
134 o
->brouter_table
->scope
= o
;
135 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
136 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
138 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, EXTERNAL_ROUTES
);
139 o
->external_table
->scope
= o
;
141 o
->external_id_table
= route_table_init ();
147 ospf6_delete (struct ospf6
*o
)
149 struct listnode
*node
, *nnode
;
150 struct ospf6_area
*oa
;
152 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
153 ospf6_area_delete (oa
);
155 ospf6_lsdb_delete (o
->lsdb
);
156 ospf6_lsdb_delete (o
->lsdb_self
);
158 ospf6_route_table_delete (o
->route_table
);
159 ospf6_route_table_delete (o
->brouter_table
);
161 ospf6_route_table_delete (o
->external_table
);
162 route_table_finish (o
->external_id_table
);
164 XFREE (MTYPE_OSPF6_TOP
, o
);
168 ospf6_enable (struct ospf6
*o
)
170 struct listnode
*node
, *nnode
;
171 struct ospf6_area
*oa
;
173 if (CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
175 UNSET_FLAG (o
->flag
, OSPF6_DISABLED
);
176 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
177 ospf6_area_enable (oa
);
182 ospf6_disable (struct ospf6
*o
)
184 struct listnode
*node
, *nnode
;
185 struct ospf6_area
*oa
;
187 if (! CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
189 SET_FLAG (o
->flag
, OSPF6_DISABLED
);
191 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
192 ospf6_area_disable (oa
);
194 ospf6_lsdb_remove_all (o
->lsdb
);
195 ospf6_route_remove_all (o
->route_table
);
196 ospf6_route_remove_all (o
->brouter_table
);
201 ospf6_maxage_remover (struct thread
*thread
)
203 struct ospf6
*o
= (struct ospf6
*) THREAD_ARG (thread
);
204 struct ospf6_area
*oa
;
205 struct ospf6_interface
*oi
;
206 struct ospf6_neighbor
*on
;
207 struct listnode
*i
, *j
, *k
;
209 o
->maxage_remover
= (struct thread
*) NULL
;
211 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
213 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
215 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, k
, on
))
217 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
218 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
226 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
228 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
229 OSPF6_LSDB_MAXAGE_REMOVER (oi
->lsdb
);
231 OSPF6_LSDB_MAXAGE_REMOVER (oa
->lsdb
);
233 OSPF6_LSDB_MAXAGE_REMOVER (o
->lsdb
);
239 ospf6_maxage_remove (struct ospf6
*o
)
241 if (o
&& ! o
->maxage_remover
)
242 o
->maxage_remover
= thread_add_event (master
, ospf6_maxage_remover
, o
, 0);
253 ospf6
= ospf6_create ();
254 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
255 ospf6_enable (ospf6
);
257 /* set current ospf point. */
258 vty
->node
= OSPF6_NODE
;
265 DEFUN (no_router_ospf6
,
271 if (ospf6
== NULL
|| CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
272 vty_out (vty
, "OSPFv3 is not running%s", VNL
);
274 ospf6_disable (ospf6
);
276 /* return to config node . */
277 vty
->node
= CONFIG_NODE
;
283 /* change Router_ID commands. */
284 DEFUN (ospf6_router_id
,
287 "Configure OSPF Router-ID\n"
294 o
= (struct ospf6
*) vty
->index
;
296 ret
= inet_pton (AF_INET
, argv
[0], &router_id
);
299 vty_out (vty
, "malformed OSPF Router-ID: %s%s", argv
[0], VNL
);
303 o
->router_id_static
= router_id
;
304 if (o
->router_id
== 0)
305 o
->router_id
= router_id
;
310 DEFUN (ospf6_interface_area
,
311 ospf6_interface_area_cmd
,
312 "interface IFNAME area A.B.C.D",
313 "Enable routing on an IPv6 interface\n"
315 "Specify the OSPF6 area ID\n"
316 "OSPF6 area ID in IPv4 address notation\n"
320 struct ospf6_area
*oa
;
321 struct ospf6_interface
*oi
;
322 struct interface
*ifp
;
325 o
= (struct ospf6
*) vty
->index
;
327 /* find/create ospf6 interface */
328 ifp
= if_get_by_name (argv
[0]);
329 oi
= (struct ospf6_interface
*) ifp
->info
;
331 oi
= ospf6_interface_create (ifp
);
334 vty_out (vty
, "%s already attached to Area %s%s",
335 oi
->interface
->name
, oi
->area
->name
, VNL
);
340 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
342 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
346 /* find/create ospf6 area */
347 oa
= ospf6_area_lookup (area_id
, o
);
349 oa
= ospf6_area_create (area_id
, o
);
351 /* attach interface to area */
352 listnode_add (oa
->if_list
, oi
); /* sort ?? */
355 SET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
358 thread_add_event (master
, interface_up
, oi
, 0);
360 /* If the router is ABR, originate summary routes */
361 if (ospf6_is_router_abr (o
))
362 ospf6_abr_enable_area (oa
);
367 DEFUN (no_ospf6_interface_area
,
368 no_ospf6_interface_area_cmd
,
369 "no interface IFNAME area A.B.C.D",
371 "Disable routing on an IPv6 interface\n"
373 "Specify the OSPF6 area ID\n"
374 "OSPF6 area ID in IPv4 address notation\n"
378 struct ospf6_interface
*oi
;
379 struct ospf6_area
*oa
;
380 struct interface
*ifp
;
383 o
= (struct ospf6
*) vty
->index
;
385 ifp
= if_lookup_by_name (argv
[0]);
388 vty_out (vty
, "No such interface %s%s", argv
[0], VNL
);
392 oi
= (struct ospf6_interface
*) ifp
->info
;
395 vty_out (vty
, "Interface %s not enabled%s", ifp
->name
, VNL
);
400 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
402 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
407 if (oi
->area
== NULL
)
409 vty_out (vty
, "No such Area-ID: %s%s", argv
[1], VNL
);
413 if (oi
->area
->area_id
!= area_id
)
415 vty_out (vty
, "Wrong Area-ID: %s is attached to area %s%s",
416 oi
->interface
->name
, oi
->area
->name
, VNL
);
420 thread_execute (master
, interface_down
, oi
, 0);
423 listnode_delete (oi
->area
->if_list
, oi
);
424 oi
->area
= (struct ospf6_area
*) NULL
;
426 /* Withdraw inter-area routes from this area, if necessary */
427 if (oa
->if_list
->count
== 0)
429 UNSET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
430 ospf6_abr_disable_area (oa
);
437 ospf6_show (struct vty
*vty
, struct ospf6
*o
)
440 struct ospf6_area
*oa
;
441 char router_id
[16], duration
[32];
442 struct timeval now
, running
;
444 /* process id, router id */
445 inet_ntop (AF_INET
, &o
->router_id
, router_id
, sizeof (router_id
));
446 vty_out (vty
, " OSPFv3 Routing Process (0) with Router-ID %s%s",
450 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &now
);
451 timersub (&now
, &o
->starttime
, &running
);
452 timerstring (&running
, duration
, sizeof (duration
));
453 vty_out (vty
, " Running %s%s", duration
, VNL
);
455 /* Redistribute configuration */
459 vty_out (vty
, " Number of AS scoped LSAs is %u%s",
460 o
->lsdb
->count
, VNL
);
463 vty_out (vty
, " Number of areas in this router is %u%s",
464 listcount (o
->area_list
), VNL
);
466 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, n
, oa
))
467 ospf6_area_show (vty
, oa
);
470 /* show top level structures */
471 DEFUN (show_ipv6_ospf6
,
478 OSPF6_CMD_CHECK_RUNNING ();
480 ospf6_show (vty
, ospf6
);
484 DEFUN (show_ipv6_ospf6_route
,
485 show_ipv6_ospf6_route_cmd
,
486 "show ipv6 ospf6 route",
493 ospf6_route_table_show (vty
, argc
, argv
, ospf6
->route_table
);
497 ALIAS (show_ipv6_ospf6_route
,
498 show_ipv6_ospf6_route_detail_cmd
,
499 "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
504 "Specify IPv6 address\n"
505 "Specify IPv6 prefix\n"
506 "Detailed information\n"
507 "Summary of route table\n"
510 DEFUN (show_ipv6_ospf6_route_match
,
511 show_ipv6_ospf6_route_match_cmd
,
512 "show ipv6 ospf6 route X:X::X:X/M match",
517 "Specify IPv6 prefix\n"
518 "Display routes which match the specified route\n"
521 const char *sargv
[CMD_ARGC_MAX
];
524 /* copy argv to sargv and then append "match" */
525 for (i
= 0; i
< argc
; i
++)
528 sargv
[sargc
++] = "match";
531 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
535 DEFUN (show_ipv6_ospf6_route_match_detail
,
536 show_ipv6_ospf6_route_match_detail_cmd
,
537 "show ipv6 ospf6 route X:X::X:X/M match detail",
542 "Specify IPv6 prefix\n"
543 "Display routes which match the specified route\n"
544 "Detailed information\n"
547 const char *sargv
[CMD_ARGC_MAX
];
550 /* copy argv to sargv and then append "match" and "detail" */
551 for (i
= 0; i
< argc
; i
++)
554 sargv
[sargc
++] = "match";
555 sargv
[sargc
++] = "detail";
558 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
562 ALIAS (show_ipv6_ospf6_route_match
,
563 show_ipv6_ospf6_route_longer_cmd
,
564 "show ipv6 ospf6 route X:X::X:X/M longer",
569 "Specify IPv6 prefix\n"
570 "Display routes longer than the specified route\n"
573 DEFUN (show_ipv6_ospf6_route_match_detail
,
574 show_ipv6_ospf6_route_longer_detail_cmd
,
575 "show ipv6 ospf6 route X:X::X:X/M longer detail",
580 "Specify IPv6 prefix\n"
581 "Display routes longer than the specified route\n"
582 "Detailed information\n"
585 ALIAS (show_ipv6_ospf6_route
,
586 show_ipv6_ospf6_route_type_cmd
,
587 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
592 "Dispaly Intra-Area routes\n"
593 "Dispaly Inter-Area routes\n"
594 "Dispaly Type-1 External routes\n"
595 "Dispaly Type-2 External routes\n"
598 DEFUN (show_ipv6_ospf6_route_type_detail
,
599 show_ipv6_ospf6_route_type_detail_cmd
,
600 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
605 "Dispaly Intra-Area routes\n"
606 "Dispaly Inter-Area routes\n"
607 "Dispaly Type-1 External routes\n"
608 "Dispaly Type-2 External routes\n"
609 "Detailed information\n"
612 const char *sargv
[CMD_ARGC_MAX
];
615 /* copy argv to sargv and then append "detail" */
616 for (i
= 0; i
< argc
; i
++)
619 sargv
[sargc
++] = "detail";
622 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
626 /* OSPF configuration write function. */
628 config_write_ospf6 (struct vty
*vty
)
631 struct listnode
*j
, *k
;
632 struct ospf6_area
*oa
;
633 struct ospf6_interface
*oi
;
635 /* OSPFv6 configuration. */
638 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
641 inet_ntop (AF_INET
, &ospf6
->router_id_static
, router_id
, sizeof (router_id
));
642 vty_out (vty
, "router ospf6%s", VNL
);
643 if (ospf6
->router_id_static
!= 0)
644 vty_out (vty
, " router-id %s%s", router_id
, VNL
);
646 ospf6_redistribute_config_write (vty
);
647 ospf6_area_config_write (vty
);
649 for (ALL_LIST_ELEMENTS_RO (ospf6
->area_list
, j
, oa
))
651 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, k
, oi
))
652 vty_out (vty
, " interface %s area %s%s",
653 oi
->interface
->name
, oa
->name
, VNL
);
655 vty_out (vty
, "!%s", VNL
);
659 /* OSPF6 node structure. */
660 static struct cmd_node ospf6_node
=
663 "%s(config-ospf6)# ",
667 /* Install ospf related commands. */
669 ospf6_top_init (void)
671 /* Install ospf6 top node. */
672 install_node (&ospf6_node
, config_write_ospf6
);
674 install_element (VIEW_NODE
, &show_ipv6_ospf6_cmd
);
675 install_element (ENABLE_NODE
, &show_ipv6_ospf6_cmd
);
676 install_element (CONFIG_NODE
, &router_ospf6_cmd
);
677 install_element (CONFIG_NODE
, &no_router_ospf6_cmd
);
679 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
680 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
681 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
682 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
683 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_longer_cmd
);
684 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_longer_detail_cmd
);
685 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_cmd
);
686 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
687 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_cmd
);
688 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
689 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_cmd
);
690 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
691 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_longer_cmd
);
692 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_longer_detail_cmd
);
693 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_cmd
);
694 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
696 install_default (OSPF6_NODE
);
697 install_element (OSPF6_NODE
, &ospf6_router_id_cmd
);
698 install_element (OSPF6_NODE
, &ospf6_interface_area_cmd
);
699 install_element (OSPF6_NODE
, &no_ospf6_interface_area_cmd
);