2 * OSPF6 Area Data Structure
3 * Copyright (C) 1999-2002 Yasuhiro Ohara
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 static int area_index
;
26 #define IS_OSPF6_DUMP_AREA (ospf6_dump_is_on (area_index))
29 ospf6_area_foreach_interface (struct ospf6_area
*o6a
, void *arg
, int val
,
30 void (*func
) (void *, int, void *))
33 struct ospf6_interface
*o6i
;
35 for (node
= listhead (o6a
->if_list
); node
; nextnode (node
))
37 o6i
= (struct ospf6_interface
*) getdata (node
);
38 (*func
) (arg
, val
, o6i
);
43 ospf6_area_foreach_neighbor (struct ospf6_area
*o6a
, void *arg
, int val
,
44 void (*func
) (void *, int, void *))
47 struct ospf6_interface
*o6i
;
49 for (node
= listhead (o6a
->if_list
); node
; nextnode (node
))
51 o6i
= (struct ospf6_interface
*) getdata (node
);
52 (*o6i
->foreach_nei
) (o6i
, arg
, val
, func
);
57 ospf6_area_maxage_remover (struct thread
*t
)
60 struct ospf6_area
*o6a
= (struct ospf6_area
*) THREAD_ARG (t
);
62 o6a
->maxage_remover
= (struct thread
*) NULL
;
65 o6a
->foreach_nei (o6a
, &count
, NBS_EXCHANGE
, ospf6_count_state
);
66 o6a
->foreach_nei (o6a
, &count
, NBS_LOADING
, ospf6_count_state
);
70 ospf6_lsdb_remove_maxage (o6a
->lsdb
);
75 ospf6_area_schedule_maxage_remover (void *arg
, int val
, void *obj
)
77 struct ospf6_area
*o6a
= (struct ospf6_area
*) obj
;
79 if (o6a
->maxage_remover
!= NULL
)
83 thread_add_event (master
, ospf6_area_maxage_remover
, o6a
, 0);
87 ospf6_area_is_stub (struct ospf6_area
*o6a
)
89 if (OSPF6_OPT_ISSET (o6a
->options
, OSPF6_OPT_E
))
95 ospf6_area_is_transit (struct ospf6_area
*o6a
)
103 ospf6_area_route_add (void *data
)
105 struct ospf6_route_req
*route
= data
;
106 struct in6_addr local
;
108 inet_pton (AF_INET6
, "::1", &local
);
109 if (! memcmp (&route
->nexthop
.address
, &local
, sizeof (struct in6_addr
)))
111 if (IS_OSPF6_DUMP_AREA
)
112 zlog_info ("AREA: Self-originated route add, ignore");
116 ospf6_route_add (route
, ospf6
->route_table
);
120 ospf6_area_route_remove (void *data
)
122 struct ospf6_route_req
*route
= data
;
123 struct in6_addr local
;
125 inet_pton (AF_INET6
, "::1", &local
);
126 if (! memcmp (&route
->nexthop
.address
, &local
, sizeof (struct in6_addr
)))
128 if (IS_OSPF6_DUMP_AREA
)
129 zlog_info ("AREA: Self-originated route remove, ignore");
133 ospf6_route_remove (route
, ospf6
->route_table
);
136 /* Make new area structure */
138 ospf6_area_create (u_int32_t area_id
)
140 struct ospf6_area
*o6a
;
143 /* allocate memory */
144 o6a
= XCALLOC (MTYPE_OSPF6_AREA
, sizeof (struct ospf6_area
));
147 inet_ntop (AF_INET
, &area_id
, o6a
->str
, sizeof (o6a
->str
));
148 o6a
->area_id
= area_id
;
149 o6a
->if_list
= list_new ();
151 o6a
->lsdb
= ospf6_lsdb_create ();
152 o6a
->spf_tree
= ospf6_spftree_create ();
154 snprintf (namebuf
, sizeof (namebuf
), "Area %s's route table", o6a
->str
);
155 o6a
->route_table
= ospf6_route_table_create (namebuf
);
156 o6a
->route_table
->hook_add
= ospf6_area_route_add
;
157 o6a
->route_table
->hook_change
= ospf6_area_route_add
;
158 o6a
->route_table
->hook_remove
= ospf6_area_route_remove
;
160 snprintf (namebuf
, sizeof (namebuf
), "Area %s's topology table", o6a
->str
);
161 o6a
->table_topology
= ospf6_route_table_create (namebuf
);
162 o6a
->table_topology
->hook_add
= ospf6_intra_topology_add
;
163 o6a
->table_topology
->hook_change
= ospf6_intra_topology_add
;
164 o6a
->table_topology
->hook_remove
= ospf6_intra_topology_remove
;
166 /* xxx, set options */
167 OSPF6_OPT_SET (o6a
->options
, OSPF6_OPT_V6
);
168 OSPF6_OPT_SET (o6a
->options
, OSPF6_OPT_E
);
169 OSPF6_OPT_SET (o6a
->options
, OSPF6_OPT_R
);
171 o6a
->foreach_if
= ospf6_area_foreach_interface
;
172 o6a
->foreach_nei
= ospf6_area_foreach_neighbor
;
178 ospf6_area_bind_top (struct ospf6_area
*o6a
, struct ospf6
*o6
)
181 CALL_CHANGE_HOOK (&area_hook
, o6a
);
186 ospf6_area_delete (struct ospf6_area
*o6a
)
189 struct ospf6_interface
*o6i
;
191 CALL_REMOVE_HOOK (&area_hook
, o6a
);
193 /* ospf6 interface list */
194 for (n
= listhead (o6a
->if_list
); n
; nextnode (n
))
196 o6i
= (struct ospf6_interface
*) getdata (n
);
197 /* ospf6_interface_delete (o6i); */
199 list_delete (o6a
->if_list
);
202 ospf6_lsdb_remove_all (o6a
->lsdb
);
204 /* spf tree terminate */
209 thread_cancel (o6a
->spf_calc
);
210 o6a
->spf_calc
= (struct thread
*) NULL
;
212 thread_cancel (o6a
->route_calc
);
213 o6a
->route_calc
= (struct thread
*) NULL
;
216 ospf6_route_table_delete (o6a
->route_table
);
218 ospf6_spftree_delete (o6a
->spf_tree
);
219 ospf6_route_table_delete (o6a
->table_topology
);
222 XFREE (MTYPE_OSPF6_AREA
, o6a
);
226 ospf6_area_lookup (u_int32_t area_id
, struct ospf6
*o6
)
228 struct ospf6_area
*o6a
;
231 for (n
= listhead (o6
->area_list
); n
; nextnode (n
))
233 o6a
= (struct ospf6_area
*) getdata (n
);
234 if (o6a
->area_id
== area_id
)
238 return (struct ospf6_area
*) NULL
;
242 ospf6_area_show (struct vty
*vty
, struct ospf6_area
*o6a
)
245 struct ospf6_interface
*o6i
;
247 vty_out (vty
, " Area %s%s", o6a
->str
, VTY_NEWLINE
);
248 vty_out (vty
, " Number of Area scoped LSAs is %u%s",
249 o6a
->lsdb
->count
, VTY_NEWLINE
);
251 ospf6_spf_statistics_show (vty
, o6a
->spf_tree
);
253 vty_out (vty
, " Interface attached to this area:");
254 for (i
= listhead (o6a
->if_list
); i
; nextnode (i
))
256 o6i
= (struct ospf6_interface
*) getdata (i
);
257 vty_out (vty
, " %s", o6i
->interface
->name
);
259 vty_out (vty
, "%s", VTY_NEWLINE
);
261 for (i
= listhead (o6a
->if_list
); i
; nextnode (i
))
263 o6i
= (struct ospf6_interface
*) getdata (i
);
264 if (listcount (o6i
->neighbor_list
) != 0)
265 ospf6_interface_statistics_show (vty
, o6i
);
270 ospf6_area_statistics_show (struct vty
*vty
, struct ospf6_area
*o6a
)
274 struct ospf6_interface
*o6i
;
276 vty_out (vty
, " Statistics of Area %s%s", o6a
->str
, VTY_NEWLINE
);
280 DEFUN (show_ipv6_ospf6_area_route
,
281 show_ipv6_ospf6_area_route_cmd
,
282 "show ipv6 ospf6 area A.B.C.D route",
291 struct ospf6_area
*o6a
;
294 OSPF6_CMD_CHECK_RUNNING ();
296 inet_pton (AF_INET
, argv
[0], &area_id
);
297 o6a
= ospf6_area_lookup (area_id
, ospf6
);
305 return ospf6_route_table_show (vty
, argc
, argv
, o6a
->route_table
);
308 ALIAS (show_ipv6_ospf6_area_route
,
309 show_ipv6_ospf6_area_route_prefix_cmd
,
310 "show ipv6 ospf6 area A.B.C.D route (X::X|detail)",
317 "Specify IPv6 address\n"
318 "Detailed information\n"
324 area_index
= ospf6_dump_install ("area", "Area information\n");
326 install_element (VIEW_NODE
, &show_ipv6_ospf6_area_route_cmd
);
327 install_element (VIEW_NODE
, &show_ipv6_ospf6_area_route_prefix_cmd
);
328 install_element (ENABLE_NODE
, &show_ipv6_ospf6_area_route_cmd
);
329 install_element (ENABLE_NODE
, &show_ipv6_ospf6_area_route_prefix_cmd
);