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 ();
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 ();
134 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
135 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
137 o
->external_table
= ospf6_route_table_create ();
138 o
->external_id_table
= route_table_init ();
144 ospf6_delete (struct ospf6
*o
)
146 struct listnode
*node
, *nnode
;
147 struct ospf6_area
*oa
;
149 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
150 ospf6_area_delete (oa
);
152 ospf6_lsdb_delete (o
->lsdb
);
153 ospf6_lsdb_delete (o
->lsdb_self
);
155 ospf6_route_table_delete (o
->route_table
);
156 ospf6_route_table_delete (o
->brouter_table
);
158 ospf6_route_table_delete (o
->external_table
);
159 route_table_finish (o
->external_id_table
);
161 XFREE (MTYPE_OSPF6_TOP
, o
);
165 ospf6_enable (struct ospf6
*o
)
167 struct listnode
*node
, *nnode
;
168 struct ospf6_area
*oa
;
170 if (CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
172 UNSET_FLAG (o
->flag
, OSPF6_DISABLED
);
173 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
174 ospf6_area_enable (oa
);
179 ospf6_disable (struct ospf6
*o
)
181 struct listnode
*node
, *nnode
;
182 struct ospf6_area
*oa
;
184 if (! CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
186 SET_FLAG (o
->flag
, OSPF6_DISABLED
);
188 for (ALL_LIST_ELEMENTS (o
->area_list
, node
, nnode
, oa
))
189 ospf6_area_disable (oa
);
191 ospf6_lsdb_remove_all (o
->lsdb
);
192 ospf6_route_remove_all (o
->route_table
);
193 ospf6_route_remove_all (o
->brouter_table
);
198 ospf6_maxage_remover (struct thread
*thread
)
200 struct ospf6
*o
= (struct ospf6
*) THREAD_ARG (thread
);
201 struct ospf6_area
*oa
;
202 struct ospf6_interface
*oi
;
203 struct ospf6_neighbor
*on
;
204 struct listnode
*i
, *j
, *k
;
206 o
->maxage_remover
= (struct thread
*) NULL
;
208 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
210 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
212 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, k
, on
))
214 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
215 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
223 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, i
, oa
))
225 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
226 OSPF6_LSDB_MAXAGE_REMOVER (oi
->lsdb
);
228 OSPF6_LSDB_MAXAGE_REMOVER (oa
->lsdb
);
230 OSPF6_LSDB_MAXAGE_REMOVER (o
->lsdb
);
236 ospf6_maxage_remove (struct ospf6
*o
)
238 if (o
&& ! o
->maxage_remover
)
239 o
->maxage_remover
= thread_add_event (master
, ospf6_maxage_remover
, o
, 0);
250 ospf6
= ospf6_create ();
251 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
252 ospf6_enable (ospf6
);
254 /* set current ospf point. */
255 vty
->node
= OSPF6_NODE
;
262 DEFUN (no_router_ospf6
,
268 if (ospf6
== NULL
|| CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
269 vty_out (vty
, "OSPFv3 is not running%s", VNL
);
271 ospf6_disable (ospf6
);
273 /* return to config node . */
274 vty
->node
= CONFIG_NODE
;
280 /* change Router_ID commands. */
281 DEFUN (ospf6_router_id
,
284 "Configure OSPF Router-ID\n"
291 o
= (struct ospf6
*) vty
->index
;
293 ret
= inet_pton (AF_INET
, argv
[0], &router_id
);
296 vty_out (vty
, "malformed OSPF Router-ID: %s%s", argv
[0], VNL
);
300 o
->router_id_static
= router_id
;
301 if (o
->router_id
== 0)
302 o
->router_id
= router_id
;
307 DEFUN (ospf6_interface_area
,
308 ospf6_interface_area_cmd
,
309 "interface IFNAME area A.B.C.D",
310 "Enable routing on an IPv6 interface\n"
312 "Specify the OSPF6 area ID\n"
313 "OSPF6 area ID in IPv4 address notation\n"
317 struct ospf6_area
*oa
;
318 struct ospf6_interface
*oi
;
319 struct interface
*ifp
;
322 o
= (struct ospf6
*) vty
->index
;
324 /* find/create ospf6 interface */
325 ifp
= if_get_by_name (argv
[0]);
326 oi
= (struct ospf6_interface
*) ifp
->info
;
328 oi
= ospf6_interface_create (ifp
);
331 vty_out (vty
, "%s already attached to Area %s%s",
332 oi
->interface
->name
, oi
->area
->name
, VNL
);
337 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
339 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
343 /* find/create ospf6 area */
344 oa
= ospf6_area_lookup (area_id
, o
);
346 oa
= ospf6_area_create (area_id
, o
);
348 /* attach interface to area */
349 listnode_add (oa
->if_list
, oi
); /* sort ?? */
352 SET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
355 thread_add_event (master
, interface_up
, oi
, 0);
357 /* If the router is ABR, originate summary routes */
358 if (ospf6_is_router_abr (o
))
359 ospf6_abr_enable_area (oa
);
364 DEFUN (no_ospf6_interface_area
,
365 no_ospf6_interface_area_cmd
,
366 "no interface IFNAME area A.B.C.D",
368 "Disable routing on an IPv6 interface\n"
370 "Specify the OSPF6 area ID\n"
371 "OSPF6 area ID in IPv4 address notation\n"
375 struct ospf6_interface
*oi
;
376 struct ospf6_area
*oa
;
377 struct interface
*ifp
;
380 o
= (struct ospf6
*) vty
->index
;
382 ifp
= if_lookup_by_name (argv
[0]);
385 vty_out (vty
, "No such interface %s%s", argv
[0], VNL
);
389 oi
= (struct ospf6_interface
*) ifp
->info
;
392 vty_out (vty
, "Interface %s not enabled%s", ifp
->name
, VNL
);
397 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
399 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
403 if (oi
->area
->area_id
!= area_id
)
405 vty_out (vty
, "Wrong Area-ID: %s is attached to area %s%s",
406 oi
->interface
->name
, oi
->area
->name
, VNL
);
410 thread_execute (master
, interface_down
, oi
, 0);
413 listnode_delete (oi
->area
->if_list
, oi
);
414 oi
->area
= (struct ospf6_area
*) NULL
;
416 /* Withdraw inter-area routes from this area, if necessary */
417 if (oa
->if_list
->count
== 0)
419 UNSET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
420 ospf6_abr_disable_area (oa
);
427 ospf6_show (struct vty
*vty
, struct ospf6
*o
)
430 struct ospf6_area
*oa
;
431 char router_id
[16], duration
[32];
432 struct timeval now
, running
;
434 /* process id, router id */
435 inet_ntop (AF_INET
, &o
->router_id
, router_id
, sizeof (router_id
));
436 vty_out (vty
, " OSPFv3 Routing Process (0) with Router-ID %s%s",
440 gettimeofday (&now
, (struct timezone
*)NULL
);
441 timersub (&now
, &o
->starttime
, &running
);
442 timerstring (&running
, duration
, sizeof (duration
));
443 vty_out (vty
, " Running %s%s", duration
, VNL
);
445 /* Redistribute configuration */
449 vty_out (vty
, " Number of AS scoped LSAs is %u%s",
450 o
->lsdb
->count
, VNL
);
453 vty_out (vty
, " Number of areas in this router is %u%s",
454 listcount (o
->area_list
), VNL
);
456 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, n
, oa
))
457 ospf6_area_show (vty
, oa
);
460 /* show top level structures */
461 DEFUN (show_ipv6_ospf6
,
468 OSPF6_CMD_CHECK_RUNNING ();
470 ospf6_show (vty
, ospf6
);
474 DEFUN (show_ipv6_ospf6_route
,
475 show_ipv6_ospf6_route_cmd
,
476 "show ipv6 ospf6 route",
483 ospf6_route_table_show (vty
, argc
, argv
, ospf6
->route_table
);
487 ALIAS (show_ipv6_ospf6_route
,
488 show_ipv6_ospf6_route_detail_cmd
,
489 "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
494 "Specify IPv6 address\n"
495 "Specify IPv6 prefix\n"
496 "Detailed information\n"
497 "Summary of route table\n"
500 DEFUN (show_ipv6_ospf6_route_match
,
501 show_ipv6_ospf6_route_match_cmd
,
502 "show ipv6 ospf6 route X:X::X:X/M match",
507 "Specify IPv6 prefix\n"
508 "Display routes which match the specified route\n"
511 const char *sargv
[CMD_ARGC_MAX
];
514 /* copy argv to sargv and then append "match" */
515 for (i
= 0; i
< argc
; i
++)
518 sargv
[sargc
++] = "match";
521 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
525 DEFUN (show_ipv6_ospf6_route_match_detail
,
526 show_ipv6_ospf6_route_match_detail_cmd
,
527 "show ipv6 ospf6 route X:X::X:X/M match detail",
532 "Specify IPv6 prefix\n"
533 "Display routes which match the specified route\n"
534 "Detailed information\n"
537 const char *sargv
[CMD_ARGC_MAX
];
540 /* copy argv to sargv and then append "match" and "detail" */
541 for (i
= 0; i
< argc
; i
++)
544 sargv
[sargc
++] = "match";
545 sargv
[sargc
++] = "detail";
548 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
552 ALIAS (show_ipv6_ospf6_route
,
553 show_ipv6_ospf6_route_type_cmd
,
554 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
559 "Dispaly Intra-Area routes\n"
560 "Dispaly Inter-Area routes\n"
561 "Dispaly Type-1 External routes\n"
562 "Dispaly Type-2 External routes\n"
565 DEFUN (show_ipv6_ospf6_route_type_detail
,
566 show_ipv6_ospf6_route_type_detail_cmd
,
567 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
572 "Dispaly Intra-Area routes\n"
573 "Dispaly Inter-Area routes\n"
574 "Dispaly Type-1 External routes\n"
575 "Dispaly Type-2 External routes\n"
576 "Detailed information\n"
579 const char *sargv
[CMD_ARGC_MAX
];
582 /* copy argv to sargv and then append "detail" */
583 for (i
= 0; i
< argc
; i
++)
586 sargv
[sargc
++] = "detail";
589 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
593 /* OSPF configuration write function. */
595 config_write_ospf6 (struct vty
*vty
)
598 struct listnode
*j
, *k
;
599 struct ospf6_area
*oa
;
600 struct ospf6_interface
*oi
;
602 /* OSPFv6 configuration. */
605 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
608 inet_ntop (AF_INET
, &ospf6
->router_id_static
, router_id
, sizeof (router_id
));
609 vty_out (vty
, "router ospf6%s", VNL
);
610 if (ospf6
->router_id_static
!= 0)
611 vty_out (vty
, " router-id %s%s", router_id
, VNL
);
613 ospf6_redistribute_config_write (vty
);
614 ospf6_area_config_write (vty
);
616 for (ALL_LIST_ELEMENTS_RO (ospf6
->area_list
, j
, oa
))
618 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, k
, oi
))
619 vty_out (vty
, " interface %s area %s%s",
620 oi
->interface
->name
, oa
->name
, VNL
);
622 vty_out (vty
, "!%s", VNL
);
626 /* OSPF6 node structure. */
627 struct cmd_node ospf6_node
=
630 "%s(config-ospf6)# ",
634 /* Install ospf related commands. */
638 /* Install ospf6 top node. */
639 install_node (&ospf6_node
, config_write_ospf6
);
641 install_element (VIEW_NODE
, &show_ipv6_ospf6_cmd
);
642 install_element (ENABLE_NODE
, &show_ipv6_ospf6_cmd
);
643 install_element (CONFIG_NODE
, &router_ospf6_cmd
);
645 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
646 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
647 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
648 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
649 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_cmd
);
650 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
651 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_cmd
);
652 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
653 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_cmd
);
654 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
655 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_cmd
);
656 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
658 install_default (OSPF6_NODE
);
659 install_element (OSPF6_NODE
, &ospf6_router_id_cmd
);
660 install_element (OSPF6_NODE
, &ospf6_interface_area_cmd
);
661 install_element (OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
662 install_element (OSPF6_NODE
, &no_router_ospf6_cmd
);