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
);
117 o
= XMALLOC (MTYPE_OSPF6_TOP
, sizeof (struct ospf6
));
118 memset (o
, 0, sizeof (struct ospf6
));
121 gettimeofday (&o
->starttime
, (struct timezone
*) NULL
);
122 o
->area_list
= list_new ();
123 o
->area_list
->cmp
= ospf6_area_cmp
;
124 o
->lsdb
= ospf6_lsdb_create (o
);
125 o
->lsdb_self
= ospf6_lsdb_create (o
);
126 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
127 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
129 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, ROUTES
);
130 o
->route_table
->scope
= o
;
131 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
132 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
134 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, BORDER_ROUTERS
);
135 o
->brouter_table
->scope
= o
;
136 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
137 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
139 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE (GLOBAL
, EXTERNAL_ROUTES
);
140 o
->external_table
->scope
= o
;
142 o
->external_id_table
= route_table_init ();
148 ospf6_delete (struct ospf6
*o
)
150 struct listnode
*node
, *nnode
;
151 struct ospf6_area
*oa
;
153 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
154 ospf6_area_delete (oa
);
156 ospf6_lsdb_delete (o
->lsdb
);
157 ospf6_lsdb_delete (o
->lsdb_self
);
159 ospf6_route_table_delete (o
->route_table
);
160 ospf6_route_table_delete (o
->brouter_table
);
162 ospf6_route_table_delete (o
->external_table
);
163 route_table_finish (o
->external_id_table
);
165 XFREE (MTYPE_OSPF6_TOP
, o
);
169 ospf6_enable (struct ospf6
*o
)
171 struct listnode
*node
, *nnode
;
172 struct ospf6_area
*oa
;
174 if (CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
176 UNSET_FLAG (o
->flag
, OSPF6_DISABLED
);
177 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
178 ospf6_area_enable (oa
);
183 ospf6_disable (struct ospf6
*o
)
185 struct listnode
*node
, *nnode
;
186 struct ospf6_area
*oa
;
188 if (! CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
190 SET_FLAG (o
->flag
, OSPF6_DISABLED
);
192 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
193 ospf6_area_disable (oa
);
195 ospf6_lsdb_remove_all (o
->lsdb
);
196 ospf6_route_remove_all (o
->route_table
);
197 ospf6_route_remove_all (o
->brouter_table
);
202 ospf6_maxage_remover (struct thread
*thread
)
204 struct ospf6
*o
= (struct ospf6
*) THREAD_ARG (thread
);
205 struct ospf6_area
*oa
;
206 struct ospf6_interface
*oi
;
207 struct ospf6_neighbor
*on
;
208 struct listnode
*i
, *j
, *k
;
210 o
->maxage_remover
= (struct thread
*) NULL
;
212 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
214 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
216 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, k
, on
))
218 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
219 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
227 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
229 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
230 OSPF6_LSDB_MAXAGE_REMOVER (oi
->lsdb
);
232 OSPF6_LSDB_MAXAGE_REMOVER (oa
->lsdb
);
234 OSPF6_LSDB_MAXAGE_REMOVER (o
->lsdb
);
240 ospf6_maxage_remove (struct ospf6
*o
)
242 if (o
&& ! o
->maxage_remover
)
243 o
->maxage_remover
= thread_add_event (master
, ospf6_maxage_remover
, o
, 0);
254 ospf6
= ospf6_create ();
255 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
256 ospf6_enable (ospf6
);
258 /* set current ospf point. */
259 vty
->node
= OSPF6_NODE
;
266 DEFUN (no_router_ospf6
,
272 if (ospf6
== NULL
|| CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
273 vty_out (vty
, "OSPFv3 is not running%s", VNL
);
275 ospf6_disable (ospf6
);
277 /* return to config node . */
278 vty
->node
= CONFIG_NODE
;
284 /* change Router_ID commands. */
285 DEFUN (ospf6_router_id
,
288 "Configure OSPF Router-ID\n"
295 o
= (struct ospf6
*) vty
->index
;
297 ret
= inet_pton (AF_INET
, argv
[0], &router_id
);
300 vty_out (vty
, "malformed OSPF Router-ID: %s%s", argv
[0], VNL
);
304 o
->router_id_static
= router_id
;
305 if (o
->router_id
== 0)
306 o
->router_id
= router_id
;
311 DEFUN (ospf6_interface_area
,
312 ospf6_interface_area_cmd
,
313 "interface IFNAME area A.B.C.D",
314 "Enable routing on an IPv6 interface\n"
316 "Specify the OSPF6 area ID\n"
317 "OSPF6 area ID in IPv4 address notation\n"
321 struct ospf6_area
*oa
;
322 struct ospf6_interface
*oi
;
323 struct interface
*ifp
;
326 o
= (struct ospf6
*) vty
->index
;
328 /* find/create ospf6 interface */
329 ifp
= if_get_by_name (argv
[0]);
330 oi
= (struct ospf6_interface
*) ifp
->info
;
332 oi
= ospf6_interface_create (ifp
);
335 vty_out (vty
, "%s already attached to Area %s%s",
336 oi
->interface
->name
, oi
->area
->name
, VNL
);
341 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
343 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
347 /* find/create ospf6 area */
348 oa
= ospf6_area_lookup (area_id
, o
);
350 oa
= ospf6_area_create (area_id
, o
);
352 /* attach interface to area */
353 listnode_add (oa
->if_list
, oi
); /* sort ?? */
356 SET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
359 thread_add_event (master
, interface_up
, oi
, 0);
361 /* If the router is ABR, originate summary routes */
362 if (ospf6_is_router_abr (o
))
363 ospf6_abr_enable_area (oa
);
368 DEFUN (no_ospf6_interface_area
,
369 no_ospf6_interface_area_cmd
,
370 "no interface IFNAME area A.B.C.D",
372 "Disable routing on an IPv6 interface\n"
374 "Specify the OSPF6 area ID\n"
375 "OSPF6 area ID in IPv4 address notation\n"
379 struct ospf6_interface
*oi
;
380 struct ospf6_area
*oa
;
381 struct interface
*ifp
;
384 o
= (struct ospf6
*) vty
->index
;
386 ifp
= if_lookup_by_name (argv
[0]);
389 vty_out (vty
, "No such interface %s%s", argv
[0], VNL
);
393 oi
= (struct ospf6_interface
*) ifp
->info
;
396 vty_out (vty
, "Interface %s not enabled%s", ifp
->name
, VNL
);
401 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
403 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
407 if (oi
->area
->area_id
!= area_id
)
409 vty_out (vty
, "Wrong Area-ID: %s is attached to area %s%s",
410 oi
->interface
->name
, oi
->area
->name
, VNL
);
414 thread_execute (master
, interface_down
, oi
, 0);
417 listnode_delete (oi
->area
->if_list
, oi
);
418 oi
->area
= (struct ospf6_area
*) NULL
;
420 /* Withdraw inter-area routes from this area, if necessary */
421 if (oa
->if_list
->count
== 0)
423 UNSET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
424 ospf6_abr_disable_area (oa
);
431 ospf6_show (struct vty
*vty
, struct ospf6
*o
)
434 struct ospf6_area
*oa
;
435 char router_id
[16], duration
[32];
436 struct timeval now
, running
;
438 /* process id, router id */
439 inet_ntop (AF_INET
, &o
->router_id
, router_id
, sizeof (router_id
));
440 vty_out (vty
, " OSPFv3 Routing Process (0) with Router-ID %s%s",
444 gettimeofday (&now
, (struct timezone
*)NULL
);
445 timersub (&now
, &o
->starttime
, &running
);
446 timerstring (&running
, duration
, sizeof (duration
));
447 vty_out (vty
, " Running %s%s", duration
, VNL
);
449 /* Redistribute configuration */
453 vty_out (vty
, " Number of AS scoped LSAs is %u%s",
454 o
->lsdb
->count
, VNL
);
457 vty_out (vty
, " Number of areas in this router is %u%s",
458 listcount (o
->area_list
), VNL
);
460 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, n
, oa
))
461 ospf6_area_show (vty
, oa
);
464 /* show top level structures */
465 DEFUN (show_ipv6_ospf6
,
472 OSPF6_CMD_CHECK_RUNNING ();
474 ospf6_show (vty
, ospf6
);
478 DEFUN (show_ipv6_ospf6_route
,
479 show_ipv6_ospf6_route_cmd
,
480 "show ipv6 ospf6 route",
487 ospf6_route_table_show (vty
, argc
, argv
, ospf6
->route_table
);
491 ALIAS (show_ipv6_ospf6_route
,
492 show_ipv6_ospf6_route_detail_cmd
,
493 "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
498 "Specify IPv6 address\n"
499 "Specify IPv6 prefix\n"
500 "Detailed information\n"
501 "Summary of route table\n"
504 DEFUN (show_ipv6_ospf6_route_match
,
505 show_ipv6_ospf6_route_match_cmd
,
506 "show ipv6 ospf6 route X:X::X:X/M match",
511 "Specify IPv6 prefix\n"
512 "Display routes which match the specified route\n"
515 const char *sargv
[CMD_ARGC_MAX
];
518 /* copy argv to sargv and then append "match" */
519 for (i
= 0; i
< argc
; i
++)
522 sargv
[sargc
++] = "match";
525 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
529 DEFUN (show_ipv6_ospf6_route_match_detail
,
530 show_ipv6_ospf6_route_match_detail_cmd
,
531 "show ipv6 ospf6 route X:X::X:X/M match detail",
536 "Specify IPv6 prefix\n"
537 "Display routes which match the specified route\n"
538 "Detailed information\n"
541 const char *sargv
[CMD_ARGC_MAX
];
544 /* copy argv to sargv and then append "match" and "detail" */
545 for (i
= 0; i
< argc
; i
++)
548 sargv
[sargc
++] = "match";
549 sargv
[sargc
++] = "detail";
552 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
556 ALIAS (show_ipv6_ospf6_route_match
,
557 show_ipv6_ospf6_route_longer_cmd
,
558 "show ipv6 ospf6 route X:X::X:X/M longer",
563 "Specify IPv6 prefix\n"
564 "Display routes longer than the specified route\n"
567 DEFUN (show_ipv6_ospf6_route_match_detail
,
568 show_ipv6_ospf6_route_longer_detail_cmd
,
569 "show ipv6 ospf6 route X:X::X:X/M longer detail",
574 "Specify IPv6 prefix\n"
575 "Display routes longer than the specified route\n"
576 "Detailed information\n"
579 ALIAS (show_ipv6_ospf6_route
,
580 show_ipv6_ospf6_route_type_cmd
,
581 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
586 "Dispaly Intra-Area routes\n"
587 "Dispaly Inter-Area routes\n"
588 "Dispaly Type-1 External routes\n"
589 "Dispaly Type-2 External routes\n"
592 DEFUN (show_ipv6_ospf6_route_type_detail
,
593 show_ipv6_ospf6_route_type_detail_cmd
,
594 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
599 "Dispaly Intra-Area routes\n"
600 "Dispaly Inter-Area routes\n"
601 "Dispaly Type-1 External routes\n"
602 "Dispaly Type-2 External routes\n"
603 "Detailed information\n"
606 const char *sargv
[CMD_ARGC_MAX
];
609 /* copy argv to sargv and then append "detail" */
610 for (i
= 0; i
< argc
; i
++)
613 sargv
[sargc
++] = "detail";
616 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
620 /* OSPF configuration write function. */
622 config_write_ospf6 (struct vty
*vty
)
625 struct listnode
*j
, *k
;
626 struct ospf6_area
*oa
;
627 struct ospf6_interface
*oi
;
629 /* OSPFv6 configuration. */
632 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
635 inet_ntop (AF_INET
, &ospf6
->router_id_static
, router_id
, sizeof (router_id
));
636 vty_out (vty
, "router ospf6%s", VNL
);
637 if (ospf6
->router_id_static
!= 0)
638 vty_out (vty
, " router-id %s%s", router_id
, VNL
);
640 ospf6_redistribute_config_write (vty
);
641 ospf6_area_config_write (vty
);
643 for (ALL_LIST_ELEMENTS_RO (ospf6
->area_list
, j
, oa
))
645 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, k
, oi
))
646 vty_out (vty
, " interface %s area %s%s",
647 oi
->interface
->name
, oa
->name
, VNL
);
649 vty_out (vty
, "!%s", VNL
);
653 /* OSPF6 node structure. */
654 struct cmd_node ospf6_node
=
657 "%s(config-ospf6)# ",
661 /* Install ospf related commands. */
665 /* Install ospf6 top node. */
666 install_node (&ospf6_node
, config_write_ospf6
);
668 install_element (VIEW_NODE
, &show_ipv6_ospf6_cmd
);
669 install_element (ENABLE_NODE
, &show_ipv6_ospf6_cmd
);
670 install_element (CONFIG_NODE
, &router_ospf6_cmd
);
672 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
673 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
674 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
675 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
676 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_longer_cmd
);
677 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_longer_detail_cmd
);
678 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_cmd
);
679 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
680 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_cmd
);
681 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
682 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_cmd
);
683 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
684 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_longer_cmd
);
685 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_longer_detail_cmd
);
686 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_cmd
);
687 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
689 install_default (OSPF6_NODE
);
690 install_element (OSPF6_NODE
, &ospf6_router_id_cmd
);
691 install_element (OSPF6_NODE
, &ospf6_interface_area_cmd
);
692 install_element (OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
693 install_element (OSPF6_NODE
, &no_router_ospf6_cmd
);