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
)
147 struct ospf6_area
*oa
;
149 for (i
= listhead (o
->area_list
); i
; nextnode (i
))
151 oa
= (struct ospf6_area
*) getdata (i
);
152 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
)
171 struct ospf6_area
*oa
;
173 if (CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
175 UNSET_FLAG (o
->flag
, OSPF6_DISABLED
);
176 for (i
= listhead (o
->area_list
); i
; nextnode (i
))
178 oa
= (struct ospf6_area
*) getdata (i
);
179 ospf6_area_enable (oa
);
185 ospf6_disable (struct ospf6
*o
)
188 struct ospf6_area
*oa
;
190 if (! CHECK_FLAG (o
->flag
, OSPF6_DISABLED
))
192 SET_FLAG (o
->flag
, OSPF6_DISABLED
);
193 for (i
= listhead (o
->area_list
); i
; nextnode (i
))
195 oa
= (struct ospf6_area
*) getdata (i
);
196 ospf6_area_disable (oa
);
199 ospf6_lsdb_remove_all (o
->lsdb
);
200 ospf6_route_remove_all (o
->route_table
);
201 ospf6_route_remove_all (o
->brouter_table
);
206 ospf6_maxage_remover (struct thread
*thread
)
208 struct ospf6
*o
= (struct ospf6
*) THREAD_ARG (thread
);
209 struct ospf6_area
*oa
;
210 struct ospf6_interface
*oi
;
211 struct ospf6_neighbor
*on
;
214 o
->maxage_remover
= (struct thread
*) NULL
;
216 for (i
= listhead (o
->area_list
); i
; nextnode (i
))
218 oa
= (struct ospf6_area
*) getdata (i
);
219 for (j
= listhead (oa
->if_list
); j
; nextnode (j
))
221 oi
= (struct ospf6_interface
*) getdata (j
);
222 for (k
= listhead (oi
->neighbor_list
); k
; nextnode (k
))
224 on
= (struct ospf6_neighbor
*) getdata (k
);
225 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
226 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
234 for (i
= listhead (o
->area_list
); i
; nextnode (i
))
236 oa
= (struct ospf6_area
*) getdata (i
);
237 for (j
= listhead (oa
->if_list
); j
; nextnode (j
))
239 oi
= (struct ospf6_interface
*) getdata (j
);
240 OSPF6_LSDB_MAXAGE_REMOVER (oi
->lsdb
);
242 OSPF6_LSDB_MAXAGE_REMOVER (oa
->lsdb
);
244 OSPF6_LSDB_MAXAGE_REMOVER (o
->lsdb
);
250 ospf6_maxage_remove (struct ospf6
*o
)
252 if (o
&& ! o
->maxage_remover
)
253 o
->maxage_remover
= thread_add_event (master
, ospf6_maxage_remover
, o
, 0);
264 ospf6
= ospf6_create ();
265 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
266 ospf6_enable (ospf6
);
268 /* set current ospf point. */
269 vty
->node
= OSPF6_NODE
;
276 DEFUN (no_router_ospf6
,
282 if (ospf6
== NULL
|| CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
283 vty_out (vty
, "OSPFv3 is not running%s", VNL
);
285 ospf6_disable (ospf6
);
287 /* return to config node . */
288 vty
->node
= CONFIG_NODE
;
294 /* change Router_ID commands. */
295 DEFUN (ospf6_router_id
,
298 "Configure OSPF Router-ID\n"
305 o
= (struct ospf6
*) vty
->index
;
307 ret
= inet_pton (AF_INET
, argv
[0], &router_id
);
310 vty_out (vty
, "malformed OSPF Router-ID: %s%s", argv
[0], VNL
);
314 o
->router_id
= router_id
;
318 DEFUN (ospf6_interface_area
,
319 ospf6_interface_area_cmd
,
320 "interface IFNAME area A.B.C.D",
321 "Enable routing on an IPv6 interface\n"
323 "Specify the OSPF6 area ID\n"
324 "OSPF6 area ID in IPv4 address notation\n"
328 struct ospf6_area
*oa
;
329 struct ospf6_interface
*oi
;
330 struct interface
*ifp
;
333 o
= (struct ospf6
*) vty
->index
;
335 /* find/create ospf6 interface */
336 ifp
= if_get_by_name (argv
[0]);
337 oi
= (struct ospf6_interface
*) ifp
->info
;
339 oi
= ospf6_interface_create (ifp
);
342 vty_out (vty
, "%s already attached to Area %s%s",
343 oi
->interface
->name
, oi
->area
->name
, VNL
);
348 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
350 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
354 /* find/create ospf6 area */
355 oa
= ospf6_area_lookup (area_id
, o
);
357 oa
= ospf6_area_create (area_id
, o
);
359 /* attach interface to area */
360 listnode_add (oa
->if_list
, oi
); /* sort ?? */
363 SET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
366 thread_add_event (master
, interface_up
, oi
, 0);
368 /* If the router is ABR, originate summary routes */
369 if (ospf6_is_router_abr (o
))
370 ospf6_abr_enable_area (oa
);
375 DEFUN (no_ospf6_interface_area
,
376 no_ospf6_interface_area_cmd
,
377 "no interface IFNAME area A.B.C.D",
379 "Disable routing on an IPv6 interface\n"
381 "Specify the OSPF6 area ID\n"
382 "OSPF6 area ID in IPv4 address notation\n"
386 struct ospf6_interface
*oi
;
387 struct ospf6_area
*oa
;
388 struct interface
*ifp
;
391 o
= (struct ospf6
*) vty
->index
;
393 ifp
= if_lookup_by_name (argv
[0]);
396 vty_out (vty
, "No such interface %s%s", argv
[0], VNL
);
400 oi
= (struct ospf6_interface
*) ifp
->info
;
403 vty_out (vty
, "Interface %s not enabled%s", ifp
->name
, VNL
);
408 if (inet_pton (AF_INET
, argv
[1], &area_id
) != 1)
410 vty_out (vty
, "Invalid Area-ID: %s%s", argv
[1], VNL
);
414 if (oi
->area
->area_id
!= area_id
)
416 vty_out (vty
, "Wrong Area-ID: %s is attached to area %s%s",
417 oi
->interface
->name
, oi
->area
->name
, VNL
);
421 thread_execute (master
, interface_down
, oi
, 0);
424 listnode_delete (oi
->area
->if_list
, oi
);
425 oi
->area
= (struct ospf6_area
*) NULL
;
427 /* Withdraw inter-area routes from this area, if necessary */
428 if (oa
->if_list
->count
== 0)
430 UNSET_FLAG (oa
->flag
, OSPF6_AREA_ENABLE
);
431 ospf6_abr_disable_area (oa
);
438 ospf6_show (struct vty
*vty
, struct ospf6
*o
)
441 struct ospf6_area
*oa
;
442 char router_id
[16], duration
[32];
443 struct timeval now
, running
;
445 /* process id, router id */
446 inet_ntop (AF_INET
, &o
->router_id
, router_id
, sizeof (router_id
));
447 vty_out (vty
, " OSPFv3 Routing Process (0) with Router-ID %s%s",
451 gettimeofday (&now
, (struct timezone
*)NULL
);
452 timersub (&now
, &o
->starttime
, &running
);
453 timerstring (&running
, duration
, sizeof (duration
));
454 vty_out (vty
, " Running %s%s", duration
, VNL
);
456 /* Redistribute configuration */
460 vty_out (vty
, " Number of AS scoped LSAs is %u%s",
461 o
->lsdb
->count
, VNL
);
464 vty_out (vty
, " Number of areas in this router is %u%s",
465 listcount (o
->area_list
), VNL
);
466 for (n
= listhead (o
->area_list
); n
; nextnode (n
))
468 oa
= (struct ospf6_area
*) getdata (n
);
469 ospf6_area_show (vty
, oa
);
473 /* show top level structures */
474 DEFUN (show_ipv6_ospf6
,
481 OSPF6_CMD_CHECK_RUNNING ();
483 ospf6_show (vty
, ospf6
);
487 DEFUN (show_ipv6_ospf6_route
,
488 show_ipv6_ospf6_route_cmd
,
489 "show ipv6 ospf6 route",
496 ospf6_route_table_show (vty
, argc
, argv
, ospf6
->route_table
);
500 ALIAS (show_ipv6_ospf6_route
,
501 show_ipv6_ospf6_route_detail_cmd
,
502 "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
507 "Specify IPv6 address\n"
508 "Specify IPv6 prefix\n"
509 "Detailed information\n"
510 "Summary of route table\n"
513 DEFUN (show_ipv6_ospf6_route_match
,
514 show_ipv6_ospf6_route_match_cmd
,
515 "show ipv6 ospf6 route X:X::X:X/M match",
520 "Specify IPv6 prefix\n"
521 "Display routes which match the specified route\n"
524 char *sargv
[CMD_ARGC_MAX
];
527 /* copy argv to sargv and then append "match" */
528 for (i
= 0; i
< argc
; i
++)
531 sargv
[sargc
++] = "match";
534 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
538 DEFUN (show_ipv6_ospf6_route_match_detail
,
539 show_ipv6_ospf6_route_match_detail_cmd
,
540 "show ipv6 ospf6 route X:X::X:X/M match detail",
545 "Specify IPv6 prefix\n"
546 "Display routes which match the specified route\n"
547 "Detailed information\n"
550 char *sargv
[CMD_ARGC_MAX
];
553 /* copy argv to sargv and then append "match" and "detail" */
554 for (i
= 0; i
< argc
; i
++)
557 sargv
[sargc
++] = "match";
558 sargv
[sargc
++] = "detail";
561 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
565 ALIAS (show_ipv6_ospf6_route
,
566 show_ipv6_ospf6_route_type_cmd
,
567 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
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"
578 DEFUN (show_ipv6_ospf6_route_type_detail
,
579 show_ipv6_ospf6_route_type_detail_cmd
,
580 "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
585 "Dispaly Intra-Area routes\n"
586 "Dispaly Inter-Area routes\n"
587 "Dispaly Type-1 External routes\n"
588 "Dispaly Type-2 External routes\n"
589 "Detailed information\n"
592 char *sargv
[CMD_ARGC_MAX
];
595 /* copy argv to sargv and then append "detail" */
596 for (i
= 0; i
< argc
; i
++)
599 sargv
[sargc
++] = "detail";
602 ospf6_route_table_show (vty
, sargc
, sargv
, ospf6
->route_table
);
606 /* OSPF configuration write function. */
608 config_write_ospf6 (struct vty
*vty
)
612 struct ospf6_area
*oa
;
613 struct ospf6_interface
*oi
;
615 /* OSPFv6 configuration. */
618 if (CHECK_FLAG (ospf6
->flag
, OSPF6_DISABLED
))
621 inet_ntop (AF_INET
, &ospf6
->router_id
, router_id
, sizeof (router_id
));
622 vty_out (vty
, "router ospf6%s", VNL
);
623 vty_out (vty
, " router-id %s%s", router_id
, VNL
);
625 ospf6_redistribute_config_write (vty
);
626 ospf6_area_config_write (vty
);
628 for (j
= listhead (ospf6
->area_list
); j
; nextnode (j
))
630 oa
= (struct ospf6_area
*) getdata (j
);
631 for (k
= listhead (oa
->if_list
); k
; nextnode (k
))
633 oi
= (struct ospf6_interface
*) getdata (k
);
634 vty_out (vty
, " interface %s area %s%s",
635 oi
->interface
->name
, oa
->name
, VNL
);
638 vty_out (vty
, "!%s", VNL
);
642 /* OSPF6 node structure. */
643 struct cmd_node ospf6_node
=
646 "%s(config-ospf6)# ",
650 /* Install ospf related commands. */
654 /* Install ospf6 top node. */
655 install_node (&ospf6_node
, config_write_ospf6
);
657 install_element (VIEW_NODE
, &show_ipv6_ospf6_cmd
);
658 install_element (ENABLE_NODE
, &show_ipv6_ospf6_cmd
);
659 install_element (CONFIG_NODE
, &router_ospf6_cmd
);
661 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
662 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
663 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
664 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
665 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_cmd
);
666 install_element (VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
667 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_cmd
);
668 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_detail_cmd
);
669 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_cmd
);
670 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
671 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_cmd
);
672 install_element (ENABLE_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
674 install_default (OSPF6_NODE
);
675 install_element (OSPF6_NODE
, &ospf6_router_id_cmd
);
676 install_element (OSPF6_NODE
, &ospf6_interface_area_cmd
);
677 install_element (OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
678 install_element (OSPF6_NODE
, &no_router_ospf6_cmd
);