blob: 1861fe7a185edd8cdd2757e427ac6f51cab947fd [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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.
20 */
21
hasso508e53e2004-05-18 18:57:06 +000022#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26#include "linklist.h"
27#include "thread.h"
28#include "vty.h"
29#include "command.h"
30#include "if.h"
31#include "prefix.h"
32#include "table.h"
hasso34956b32005-06-24 08:44:02 +000033#include "plist.h"
34#include "filter.h"
hasso508e53e2004-05-18 18:57:06 +000035
hasso508e53e2004-05-18 18:57:06 +000036#include "ospf6_proto.h"
37#include "ospf6_lsa.h"
38#include "ospf6_lsdb.h"
39#include "ospf6_route.h"
40#include "ospf6_spf.h"
41#include "ospf6_top.h"
42#include "ospf6_area.h"
43#include "ospf6_interface.h"
44#include "ospf6_intra.h"
hasso049207c2004-08-04 20:02:13 +000045#include "ospf6_abr.h"
46#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000047
hasso508e53e2004-05-18 18:57:06 +000048int
49ospf6_area_cmp (void *va, void *vb)
paul718e3742002-12-13 20:15:29 +000050{
hasso508e53e2004-05-18 18:57:06 +000051 struct ospf6_area *oa = (struct ospf6_area *) va;
52 struct ospf6_area *ob = (struct ospf6_area *) vb;
hasso6452df02004-08-15 05:52:07 +000053 return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
paul718e3742002-12-13 20:15:29 +000054}
55
hasso508e53e2004-05-18 18:57:06 +000056/* schedule routing table recalculation */
Paul Jakma6ac29a52008-08-15 13:45:30 +010057static void
hasso508e53e2004-05-18 18:57:06 +000058ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000059{
hasso508e53e2004-05-18 18:57:06 +000060 switch (ntohs (lsa->header->type))
paul718e3742002-12-13 20:15:29 +000061 {
hasso508e53e2004-05-18 18:57:06 +000062 case OSPF6_LSTYPE_ROUTER:
63 case OSPF6_LSTYPE_NETWORK:
hasso1e058382004-09-01 21:36:14 +000064 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
65 {
hassoc6487d62004-12-24 06:00:11 +000066 zlog_debug ("Examin %s", lsa->name);
67 zlog_debug ("Schedule SPF Calculation for %s",
68 OSPF6_AREA (lsa->lsdb->data)->name);
hasso1e058382004-09-01 21:36:14 +000069 }
Dinesh Dutta0edf672013-08-26 03:40:23 +000070 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
71 ospf6_lsadd_to_spf_reason(lsa));
hasso508e53e2004-05-18 18:57:06 +000072 break;
paul718e3742002-12-13 20:15:29 +000073
hasso508e53e2004-05-18 18:57:06 +000074 case OSPF6_LSTYPE_INTRA_PREFIX:
75 ospf6_intra_prefix_lsa_add (lsa);
76 break;
77
78 case OSPF6_LSTYPE_INTER_PREFIX:
79 case OSPF6_LSTYPE_INTER_ROUTER:
hassoccb59b12004-08-25 09:10:37 +000080 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
hasso508e53e2004-05-18 18:57:06 +000081 break;
82
83 default:
hasso508e53e2004-05-18 18:57:06 +000084 break;
85 }
paul718e3742002-12-13 20:15:29 +000086}
87
Paul Jakma6ac29a52008-08-15 13:45:30 +010088static void
hasso508e53e2004-05-18 18:57:06 +000089ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000090{
hasso508e53e2004-05-18 18:57:06 +000091 switch (ntohs (lsa->header->type))
paul718e3742002-12-13 20:15:29 +000092 {
hasso508e53e2004-05-18 18:57:06 +000093 case OSPF6_LSTYPE_ROUTER:
94 case OSPF6_LSTYPE_NETWORK:
hasso1e058382004-09-01 21:36:14 +000095 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
96 {
hassoc6487d62004-12-24 06:00:11 +000097 zlog_debug ("LSA disappearing: %s", lsa->name);
98 zlog_debug ("Schedule SPF Calculation for %s",
hasso1e058382004-09-01 21:36:14 +000099 OSPF6_AREA (lsa->lsdb->data)->name);
100 }
Dinesh Dutta0edf672013-08-26 03:40:23 +0000101 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
102 ospf6_lsremove_to_spf_reason(lsa));
hasso508e53e2004-05-18 18:57:06 +0000103 break;
paul718e3742002-12-13 20:15:29 +0000104
hasso508e53e2004-05-18 18:57:06 +0000105 case OSPF6_LSTYPE_INTRA_PREFIX:
106 ospf6_intra_prefix_lsa_remove (lsa);
107 break;
108
109 case OSPF6_LSTYPE_INTER_PREFIX:
110 case OSPF6_LSTYPE_INTER_ROUTER:
hassoccb59b12004-08-25 09:10:37 +0000111 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
hasso508e53e2004-05-18 18:57:06 +0000112 break;
113
114 default:
hasso508e53e2004-05-18 18:57:06 +0000115 break;
116 }
117}
118
Paul Jakma6ac29a52008-08-15 13:45:30 +0100119static void
hasso508e53e2004-05-18 18:57:06 +0000120ospf6_area_route_hook_add (struct ospf6_route *route)
121{
122 struct ospf6_route *copy = ospf6_route_copy (route);
123 ospf6_route_add (copy, ospf6->route_table);
124}
125
Paul Jakma6ac29a52008-08-15 13:45:30 +0100126static void
hasso508e53e2004-05-18 18:57:06 +0000127ospf6_area_route_hook_remove (struct ospf6_route *route)
128{
129 struct ospf6_route *copy;
130
131 copy = ospf6_route_lookup_identical (route, ospf6->route_table);
132 if (copy)
133 ospf6_route_remove (copy, ospf6->route_table);
paul718e3742002-12-13 20:15:29 +0000134}
135
136/* Make new area structure */
137struct ospf6_area *
hasso508e53e2004-05-18 18:57:06 +0000138ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
paul718e3742002-12-13 20:15:29 +0000139{
hasso508e53e2004-05-18 18:57:06 +0000140 struct ospf6_area *oa;
hasso049207c2004-08-04 20:02:13 +0000141 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000142
hasso508e53e2004-05-18 18:57:06 +0000143 oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
paul718e3742002-12-13 20:15:29 +0000144
hasso508e53e2004-05-18 18:57:06 +0000145 inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
146 oa->area_id = area_id;
147 oa->if_list = list_new ();
paul718e3742002-12-13 20:15:29 +0000148
hasso6452df02004-08-15 05:52:07 +0000149 oa->lsdb = ospf6_lsdb_create (oa);
hasso508e53e2004-05-18 18:57:06 +0000150 oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
151 oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
hasso6452df02004-08-15 05:52:07 +0000152 oa->lsdb_self = ospf6_lsdb_create (oa);
paul718e3742002-12-13 20:15:29 +0000153
Paul Jakmacf1ce252006-05-15 10:46:07 +0000154 oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
155 oa->spf_table->scope = oa;
156 oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
157 oa->route_table->scope = oa;
hasso508e53e2004-05-18 18:57:06 +0000158 oa->route_table->hook_add = ospf6_area_route_hook_add;
159 oa->route_table->hook_remove = ospf6_area_route_hook_remove;
paul718e3742002-12-13 20:15:29 +0000160
Paul Jakmacf1ce252006-05-15 10:46:07 +0000161 oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
162 oa->range_table->scope = oa;
163 oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
164 oa->summary_prefix->scope = oa;
165 oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
166 oa->summary_router->scope = oa;
hasso6452df02004-08-15 05:52:07 +0000167
hasso508e53e2004-05-18 18:57:06 +0000168 /* set default options */
Dinesh Duttf41b4a02013-08-24 08:00:37 +0000169 if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
170 {
171 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
172 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
173 }
174 else
175 {
176 OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
177 OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
178 }
179
hasso508e53e2004-05-18 18:57:06 +0000180 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
paul718e3742002-12-13 20:15:29 +0000181
hasso508e53e2004-05-18 18:57:06 +0000182 oa->ospf6 = o;
183 listnode_add_sort (o->area_list, oa);
paul718e3742002-12-13 20:15:29 +0000184
hasso049207c2004-08-04 20:02:13 +0000185 /* import athoer area's routes as inter-area routes */
186 for (route = ospf6_route_head (o->route_table); route;
187 route = ospf6_route_next (route))
hasso6452df02004-08-15 05:52:07 +0000188 ospf6_abr_originate_summary_to_area (route, oa);
hasso049207c2004-08-04 20:02:13 +0000189
hasso508e53e2004-05-18 18:57:06 +0000190 return oa;
paul718e3742002-12-13 20:15:29 +0000191}
192
193void
hasso508e53e2004-05-18 18:57:06 +0000194ospf6_area_delete (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000195{
Christian Franked9628722013-03-08 21:47:35 +0100196 struct listnode *n;
hasso508e53e2004-05-18 18:57:06 +0000197 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000198
hasso6452df02004-08-15 05:52:07 +0000199 ospf6_route_table_delete (oa->range_table);
200 ospf6_route_table_delete (oa->summary_prefix);
201 ospf6_route_table_delete (oa->summary_router);
hasso049207c2004-08-04 20:02:13 +0000202
Christian Franked9628722013-03-08 21:47:35 +0100203 /* The ospf6_interface structs store configuration
204 * information which should not be lost/reset when
205 * deleting an area.
206 * So just detach the interface from the area and
207 * keep it around. */
208 for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
209 oi->area = NULL;
210
hasso508e53e2004-05-18 18:57:06 +0000211 list_delete (oa->if_list);
paul718e3742002-12-13 20:15:29 +0000212
hasso508e53e2004-05-18 18:57:06 +0000213 ospf6_lsdb_delete (oa->lsdb);
hasso6452df02004-08-15 05:52:07 +0000214 ospf6_lsdb_delete (oa->lsdb_self);
215
Tom Goff1d192342010-11-10 13:02:38 -0800216 ospf6_spf_table_finish (oa->spf_table);
hasso508e53e2004-05-18 18:57:06 +0000217 ospf6_route_table_delete (oa->spf_table);
218 ospf6_route_table_delete (oa->route_table);
paul718e3742002-12-13 20:15:29 +0000219
hasso508e53e2004-05-18 18:57:06 +0000220 THREAD_OFF (oa->thread_spf_calculation);
221 THREAD_OFF (oa->thread_route_calculation);
paul718e3742002-12-13 20:15:29 +0000222
hasso508e53e2004-05-18 18:57:06 +0000223 listnode_delete (oa->ospf6->area_list, oa);
224 oa->ospf6 = NULL;
paul718e3742002-12-13 20:15:29 +0000225
226 /* free area */
hasso508e53e2004-05-18 18:57:06 +0000227 XFREE (MTYPE_OSPF6_AREA, oa);
paul718e3742002-12-13 20:15:29 +0000228}
229
230struct ospf6_area *
hasso508e53e2004-05-18 18:57:06 +0000231ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
paul718e3742002-12-13 20:15:29 +0000232{
hasso508e53e2004-05-18 18:57:06 +0000233 struct ospf6_area *oa;
hasso52dc7ee2004-09-23 19:18:23 +0000234 struct listnode *n;
paul718e3742002-12-13 20:15:29 +0000235
paul1eb8ef22005-04-07 07:30:20 +0000236 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
237 if (oa->area_id == area_id)
238 return oa;
paul718e3742002-12-13 20:15:29 +0000239
240 return (struct ospf6_area *) NULL;
241}
242
Paul Jakma6ac29a52008-08-15 13:45:30 +0100243static struct ospf6_area *
hasso6452df02004-08-15 05:52:07 +0000244ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
245{
246 struct ospf6_area *oa;
247 oa = ospf6_area_lookup (area_id, o);
248 if (oa == NULL)
249 oa = ospf6_area_create (area_id, o);
250 return oa;
251}
252
paul718e3742002-12-13 20:15:29 +0000253void
hasso508e53e2004-05-18 18:57:06 +0000254ospf6_area_enable (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000255{
paul1eb8ef22005-04-07 07:30:20 +0000256 struct listnode *node, *nnode;
hasso508e53e2004-05-18 18:57:06 +0000257 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000258
hasso6452df02004-08-15 05:52:07 +0000259 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
paul718e3742002-12-13 20:15:29 +0000260
paul1eb8ef22005-04-07 07:30:20 +0000261 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
262 ospf6_interface_enable (oi);
Christian Franked9628722013-03-08 21:47:35 +0100263 ospf6_abr_enable_area (oa);
paul718e3742002-12-13 20:15:29 +0000264}
265
266void
hasso508e53e2004-05-18 18:57:06 +0000267ospf6_area_disable (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000268{
paul1eb8ef22005-04-07 07:30:20 +0000269 struct listnode *node, *nnode;
hasso508e53e2004-05-18 18:57:06 +0000270 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000271
hasso6452df02004-08-15 05:52:07 +0000272 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
hasso508e53e2004-05-18 18:57:06 +0000273
paul1eb8ef22005-04-07 07:30:20 +0000274 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
275 ospf6_interface_disable (oi);
Christian Franked9628722013-03-08 21:47:35 +0100276
277 ospf6_abr_disable_area (oa);
278 ospf6_lsdb_remove_all (oa->lsdb);
279 ospf6_lsdb_remove_all (oa->lsdb_self);
280
281 ospf6_spf_table_finish(oa->spf_table);
282 ospf6_route_remove_all(oa->route_table);
283
284 THREAD_OFF (oa->thread_spf_calculation);
285 THREAD_OFF (oa->thread_route_calculation);
286
287 THREAD_OFF (oa->thread_router_lsa);
288 THREAD_OFF (oa->thread_intra_prefix_lsa);
paul718e3742002-12-13 20:15:29 +0000289}
290
David Lamparter6b0655a2014-06-04 06:53:35 +0200291
hasso508e53e2004-05-18 18:57:06 +0000292void
293ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
294{
hasso52dc7ee2004-09-23 19:18:23 +0000295 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000296 struct ospf6_interface *oi;
297
hasso049207c2004-08-04 20:02:13 +0000298 vty_out (vty, " Area %s%s", oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000299 vty_out (vty, " Number of Area scoped LSAs is %u%s",
hasso049207c2004-08-04 20:02:13 +0000300 oa->lsdb->count, VNL);
hasso508e53e2004-05-18 18:57:06 +0000301
302 vty_out (vty, " Interface attached to this area:");
paul1eb8ef22005-04-07 07:30:20 +0000303 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
304 vty_out (vty, " %s", oi->interface->name);
305
hasso049207c2004-08-04 20:02:13 +0000306 vty_out (vty, "%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000307}
308
309
hasso049207c2004-08-04 20:02:13 +0000310#define OSPF6_CMD_AREA_LOOKUP(str, oa) \
311{ \
312 u_int32_t area_id = 0; \
313 if (inet_pton (AF_INET, str, &area_id) != 1) \
314 { \
315 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
316 return CMD_SUCCESS; \
317 } \
318 oa = ospf6_area_lookup (area_id, ospf6); \
319 if (oa == NULL) \
320 { \
321 vty_out (vty, "No such Area: %s%s", str, VNL); \
322 return CMD_SUCCESS; \
323 } \
hasso508e53e2004-05-18 18:57:06 +0000324}
325
hasso6452df02004-08-15 05:52:07 +0000326#define OSPF6_CMD_AREA_GET(str, oa) \
327{ \
328 u_int32_t area_id = 0; \
329 if (inet_pton (AF_INET, str, &area_id) != 1) \
330 { \
331 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
332 return CMD_SUCCESS; \
333 } \
334 oa = ospf6_area_get (area_id, ospf6); \
335}
336
337DEFUN (area_range,
338 area_range_cmd,
339 "area A.B.C.D range X:X::X:X/M",
340 "OSPF area parameters\n"
341 OSPF6_AREA_ID_STR
342 "Configured address range\n"
343 "Specify IPv6 prefix\n"
344 )
345{
346 int ret;
347 struct ospf6_area *oa;
348 struct prefix prefix;
349 struct ospf6_route *range;
350
351 OSPF6_CMD_AREA_GET (argv[0], oa);
352 argc--;
353 argv++;
354
355 ret = str2prefix (argv[0], &prefix);
356 if (ret != 1 || prefix.family != AF_INET6)
357 {
358 vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
359 return CMD_SUCCESS;
360 }
361 argc--;
362 argv++;
363
364 range = ospf6_route_lookup (&prefix, oa->range_table);
365 if (range == NULL)
366 {
367 range = ospf6_route_create ();
368 range->type = OSPF6_DEST_TYPE_RANGE;
369 range->prefix = prefix;
370 }
371
372 if (argc)
373 {
374 if (! strcmp (argv[0], "not-advertise"))
375 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
376 else if (! strcmp (argv[0], "advertise"))
377 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
378 }
379
Jon86f9e5a2009-02-11 17:22:03 -0800380 if (range->rnode)
381 {
382 vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
383 return CMD_WARNING;
384 }
385
hasso6452df02004-08-15 05:52:07 +0000386 ospf6_route_add (range, oa->range_table);
387 return CMD_SUCCESS;
388}
389
390ALIAS (area_range,
391 area_range_advertise_cmd,
392 "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
393 "OSPF area parameters\n"
394 OSPF6_AREA_ID_STR
395 "Configured address range\n"
396 "Specify IPv6 prefix\n"
Paul Jakma6ac29a52008-08-15 13:45:30 +0100397 )
hasso6452df02004-08-15 05:52:07 +0000398
399DEFUN (no_area_range,
400 no_area_range_cmd,
401 "no area A.B.C.D range X:X::X:X/M",
402 "OSPF area parameters\n"
403 OSPF6_AREA_ID_STR
404 "Configured address range\n"
405 "Specify IPv6 prefix\n"
406 )
407{
408 int ret;
409 struct ospf6_area *oa;
410 struct prefix prefix;
411 struct ospf6_route *range;
412
413 OSPF6_CMD_AREA_GET (argv[0], oa);
414 argc--;
415 argv++;
416
417 ret = str2prefix (argv[0], &prefix);
418 if (ret != 1 || prefix.family != AF_INET6)
419 {
420 vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
421 return CMD_SUCCESS;
422 }
423
424 range = ospf6_route_lookup (&prefix, oa->range_table);
425 if (range == NULL)
426 {
427 vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
428 return CMD_SUCCESS;
429 }
430
431 ospf6_route_remove (range, oa->range_table);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700432
hasso6452df02004-08-15 05:52:07 +0000433 return CMD_SUCCESS;
434}
435
436void
437ospf6_area_config_write (struct vty *vty)
438{
hasso52dc7ee2004-09-23 19:18:23 +0000439 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000440 struct ospf6_area *oa;
441 struct ospf6_route *range;
442 char buf[128];
443
paul1eb8ef22005-04-07 07:30:20 +0000444 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
hasso6452df02004-08-15 05:52:07 +0000445 {
hasso6452df02004-08-15 05:52:07 +0000446 for (range = ospf6_route_head (oa->range_table); range;
447 range = ospf6_route_next (range))
448 {
449 prefix2str (&range->prefix, buf, sizeof (buf));
450 vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
451 }
Jon Andersson5fdaa042011-09-13 15:47:14 +0400452 if (PREFIX_NAME_IN (oa))
453 vty_out (vty, " area %s filter-list prefix %s in%s",
454 oa->name, PREFIX_NAME_IN (oa), VNL);
455 if (PREFIX_NAME_OUT (oa))
456 vty_out (vty, " area %s filter-list prefix %s out%s",
457 oa->name, PREFIX_NAME_OUT (oa), VNL);
458 if (IMPORT_NAME (oa))
459 vty_out (vty, " area %s import-list %s%s",
460 oa->name, IMPORT_NAME (oa), VNL);
461 if (EXPORT_NAME (oa))
462 vty_out (vty, " area %s export-list %s%s",
463 oa->name, EXPORT_NAME (oa), VNL);
hasso6452df02004-08-15 05:52:07 +0000464 }
465}
466
hasso34956b32005-06-24 08:44:02 +0000467DEFUN (area_filter_list,
468 area_filter_list_cmd,
469 "area A.B.C.D filter-list prefix WORD (in|out)",
470 "OSPFv6 area parameters\n"
471 "OSPFv6 area ID in IP address format\n"
472 "Filter networks between OSPFv6 areas\n"
473 "Filter prefixes between OSPFv6 areas\n"
474 "Name of an IPv6 prefix-list\n"
475 "Filter networks sent to this area\n"
476 "Filter networks sent from this area\n")
477{
478 struct ospf6_area *area;
479 struct prefix_list *plist;
480
481 OSPF6_CMD_AREA_GET (argv[0], area);
482 argc--;
483 argv++;
484
Christian Hammers75d044d2011-09-12 14:23:05 +0400485 plist = prefix_list_lookup (AFI_IP6, argv[0]);
486 if (strncmp (argv[1], "in", 2) == 0)
hasso34956b32005-06-24 08:44:02 +0000487 {
488 PREFIX_LIST_IN (area) = plist;
489 if (PREFIX_NAME_IN (area))
490 free (PREFIX_NAME_IN (area));
491
Christian Hammers75d044d2011-09-12 14:23:05 +0400492 PREFIX_NAME_IN (area) = strdup (argv[0]);
hasso34956b32005-06-24 08:44:02 +0000493 ospf6_abr_reimport (area);
494 }
495 else
496 {
497 PREFIX_LIST_OUT (area) = plist;
498 if (PREFIX_NAME_OUT (area))
499 free (PREFIX_NAME_OUT (area));
500
Christian Hammers75d044d2011-09-12 14:23:05 +0400501 PREFIX_NAME_OUT (area) = strdup (argv[0]);
hasso34956b32005-06-24 08:44:02 +0000502 ospf6_abr_enable_area (area);
503 }
504
505 return CMD_SUCCESS;
506}
507
508DEFUN (no_area_filter_list,
509 no_area_filter_list_cmd,
510 "no area A.B.C.D filter-list prefix WORD (in|out)",
511 NO_STR
512 "OSPFv6 area parameters\n"
513 "OSPFv6 area ID in IP address format\n"
514 "Filter networks between OSPFv6 areas\n"
515 "Filter prefixes between OSPFv6 areas\n"
516 "Name of an IPv6 prefix-list\n"
517 "Filter networks sent to this area\n"
518 "Filter networks sent from this area\n")
519{
520 struct ospf6_area *area;
hasso34956b32005-06-24 08:44:02 +0000521
522 OSPF6_CMD_AREA_GET (argv[0], area);
523 argc--;
524 argv++;
525
Christian Hammers75d044d2011-09-12 14:23:05 +0400526 if (strncmp (argv[1], "in", 2) == 0)
hasso34956b32005-06-24 08:44:02 +0000527 {
528 if (PREFIX_NAME_IN (area))
Christian Hammers75d044d2011-09-12 14:23:05 +0400529 if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
hasso34956b32005-06-24 08:44:02 +0000530 return CMD_SUCCESS;
531
532 PREFIX_LIST_IN (area) = NULL;
533 if (PREFIX_NAME_IN (area))
534 free (PREFIX_NAME_IN (area));
535
536 PREFIX_NAME_IN (area) = NULL;
537 ospf6_abr_reimport (area);
538 }
539 else
540 {
541 if (PREFIX_NAME_OUT (area))
Christian Hammers75d044d2011-09-12 14:23:05 +0400542 if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
hasso34956b32005-06-24 08:44:02 +0000543 return CMD_SUCCESS;
544
545 PREFIX_LIST_OUT (area) = NULL;
546 if (PREFIX_NAME_OUT (area))
547 free (PREFIX_NAME_OUT (area));
548
549 PREFIX_NAME_OUT (area) = NULL;
550 ospf6_abr_enable_area (area);
551 }
552
553 return CMD_SUCCESS;
554}
555
556DEFUN (area_import_list,
557 area_import_list_cmd,
558 "area A.B.C.D import-list NAME",
559 "OSPFv6 area parameters\n"
560 "OSPFv6 area ID in IP address format\n"
561 "Set the filter for networks from other areas announced to the specified one\n"
562 "Name of the acess-list\n")
563{
564 struct ospf6_area *area;
565 struct access_list *list;
566
567 OSPF6_CMD_AREA_GET(argv[0], area);
568
569 list = access_list_lookup (AFI_IP6, argv[1]);
570
571 IMPORT_LIST (area) = list;
572
573 if (IMPORT_NAME (area))
574 free (IMPORT_NAME (area));
575
576 IMPORT_NAME (area) = strdup (argv[1]);
577 ospf6_abr_reimport (area);
578
579 return CMD_SUCCESS;
580}
581
582DEFUN (no_area_import_list,
583 no_area_import_list_cmd,
584 "no area A.B.C.D import-list NAME",
585 "OSPFv6 area parameters\n"
586 "OSPFv6 area ID in IP address format\n"
587 "Unset the filter for networks announced to other areas\n"
588 "NAme of the access-list\n")
589{
590 struct ospf6_area *area;
591
592 OSPF6_CMD_AREA_GET(argv[0], area);
593
594 IMPORT_LIST (area) = 0;
595
596 if (IMPORT_NAME (area))
597 free (IMPORT_NAME (area));
598
599 IMPORT_NAME (area) = NULL;
600 ospf6_abr_reimport (area);
601
602 return CMD_SUCCESS;
603}
604
605DEFUN (area_export_list,
606 area_export_list_cmd,
607 "area A.B.C.D export-list NAME",
608 "OSPFv6 area parameters\n"
609 "OSPFv6 area ID in IP address format\n"
610 "Set the filter for networks announced to other areas\n"
611 "Name of the acess-list\n")
612{
613 struct ospf6_area *area;
614 struct access_list *list;
615
616 OSPF6_CMD_AREA_GET(argv[0], area);
617
618 list = access_list_lookup (AFI_IP6, argv[1]);
619
620 EXPORT_LIST (area) = list;
621
622 if (EXPORT_NAME (area))
623 free (EXPORT_NAME (area));
624
625 EXPORT_NAME (area) = strdup (argv[1]);
626 ospf6_abr_enable_area (area);
627
628 return CMD_SUCCESS;
629}
630
631DEFUN (no_area_export_list,
632 no_area_export_list_cmd,
633 "no area A.B.C.D export-list NAME",
634 "OSPFv6 area parameters\n"
635 "OSPFv6 area ID in IP address format\n"
636 "Unset the filter for networks announced to other areas\n"
637 "Name of the access-list\n")
638{
639 struct ospf6_area *area;
640
641 OSPF6_CMD_AREA_GET(argv[0], area);
642
643 EXPORT_LIST (area) = 0;
644
645 if (EXPORT_NAME (area))
646 free (EXPORT_NAME (area));
647
648 EXPORT_NAME (area) = NULL;
649 ospf6_abr_enable_area (area);
650
651 return CMD_SUCCESS;
652}
653
hasso508e53e2004-05-18 18:57:06 +0000654DEFUN (show_ipv6_ospf6_spf_tree,
655 show_ipv6_ospf6_spf_tree_cmd,
656 "show ipv6 ospf6 spf tree",
657 SHOW_STR
658 IP6_STR
659 OSPF6_STR
660 "Shortest Path First caculation\n"
661 "Show SPF tree\n")
662{
hasso52dc7ee2004-09-23 19:18:23 +0000663 struct listnode *node;
hasso508e53e2004-05-18 18:57:06 +0000664 struct ospf6_area *oa;
665 struct ospf6_vertex *root;
666 struct ospf6_route *route;
667 struct prefix prefix;
668
Vipin Kumarf972dec2015-05-19 18:03:41 -0700669 OSPF6_CMD_CHECK_RUNNING ();
670
hasso508e53e2004-05-18 18:57:06 +0000671 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
paul1eb8ef22005-04-07 07:30:20 +0000672
673 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
hasso508e53e2004-05-18 18:57:06 +0000674 {
hasso508e53e2004-05-18 18:57:06 +0000675 route = ospf6_route_lookup (&prefix, oa->spf_table);
676 if (route == NULL)
677 {
678 vty_out (vty, "LS entry for root not found in area %s%s",
hasso049207c2004-08-04 20:02:13 +0000679 oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000680 continue;
681 }
682 root = (struct ospf6_vertex *) route->route_option;
683 ospf6_spf_display_subtree (vty, "", 0, root);
684 }
685
686 return CMD_SUCCESS;
687}
688
689DEFUN (show_ipv6_ospf6_area_spf_tree,
690 show_ipv6_ospf6_area_spf_tree_cmd,
691 "show ipv6 ospf6 area A.B.C.D spf tree",
692 SHOW_STR
693 IP6_STR
694 OSPF6_STR
695 OSPF6_AREA_STR
696 OSPF6_AREA_ID_STR
697 "Shortest Path First caculation\n"
698 "Show SPF tree\n")
699{
700 u_int32_t area_id;
701 struct ospf6_area *oa;
702 struct ospf6_vertex *root;
703 struct ospf6_route *route;
704 struct prefix prefix;
705
Vipin Kumarf972dec2015-05-19 18:03:41 -0700706 OSPF6_CMD_CHECK_RUNNING ();
707
hasso508e53e2004-05-18 18:57:06 +0000708 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
709
710 if (inet_pton (AF_INET, argv[0], &area_id) != 1)
711 {
hasso049207c2004-08-04 20:02:13 +0000712 vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
hasso508e53e2004-05-18 18:57:06 +0000713 return CMD_SUCCESS;
714 }
715 oa = ospf6_area_lookup (area_id, ospf6);
716 if (oa == NULL)
717 {
hasso049207c2004-08-04 20:02:13 +0000718 vty_out (vty, "No such Area: %s%s", argv[0], VNL);
hasso508e53e2004-05-18 18:57:06 +0000719 return CMD_SUCCESS;
720 }
721
722 route = ospf6_route_lookup (&prefix, oa->spf_table);
723 if (route == NULL)
724 {
725 vty_out (vty, "LS entry for root not found in area %s%s",
hasso049207c2004-08-04 20:02:13 +0000726 oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000727 return CMD_SUCCESS;
728 }
729 root = (struct ospf6_vertex *) route->route_option;
730 ospf6_spf_display_subtree (vty, "", 0, root);
731
732 return CMD_SUCCESS;
733}
734
hasso508e53e2004-05-18 18:57:06 +0000735DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
736 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
737 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
738 SHOW_STR
739 IP6_STR
740 OSPF6_STR
741 "Shortest Path First caculation\n"
742 "Show SPF tree\n"
743 "Specify root's router-id to calculate another router's SPF tree\n")
744{
745 u_int32_t area_id;
746 struct ospf6_area *oa;
747 struct ospf6_vertex *root;
748 struct ospf6_route *route;
749 struct prefix prefix;
750 u_int32_t router_id;
751 struct ospf6_route_table *spf_table;
752 unsigned char tmp_debug_ospf6_spf = 0;
753
Vipin Kumarf972dec2015-05-19 18:03:41 -0700754 OSPF6_CMD_CHECK_RUNNING ();
755
hasso508e53e2004-05-18 18:57:06 +0000756 inet_pton (AF_INET, argv[0], &router_id);
757 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
758
759 if (inet_pton (AF_INET, argv[1], &area_id) != 1)
760 {
hasso049207c2004-08-04 20:02:13 +0000761 vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
hasso508e53e2004-05-18 18:57:06 +0000762 return CMD_SUCCESS;
763 }
764 oa = ospf6_area_lookup (area_id, ospf6);
765 if (oa == NULL)
766 {
hasso049207c2004-08-04 20:02:13 +0000767 vty_out (vty, "No such Area: %s%s", argv[1], VNL);
hasso508e53e2004-05-18 18:57:06 +0000768 return CMD_SUCCESS;
769 }
770
771 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
772 conf_debug_ospf6_spf = 0;
773
Paul Jakmacf1ce252006-05-15 10:46:07 +0000774 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
hasso508e53e2004-05-18 18:57:06 +0000775 ospf6_spf_calculation (router_id, spf_table, oa);
776
777 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
778
779 route = ospf6_route_lookup (&prefix, spf_table);
780 if (route == NULL)
781 {
782 ospf6_spf_table_finish (spf_table);
783 ospf6_route_table_delete (spf_table);
784 return CMD_SUCCESS;
785 }
786 root = (struct ospf6_vertex *) route->route_option;
787 ospf6_spf_display_subtree (vty, "", 0, root);
788
789 ospf6_spf_table_finish (spf_table);
790 ospf6_route_table_delete (spf_table);
791
792 return CMD_SUCCESS;
793}
paul718e3742002-12-13 20:15:29 +0000794
795void
Paul Jakma6ac29a52008-08-15 13:45:30 +0100796ospf6_area_init (void)
paul718e3742002-12-13 20:15:29 +0000797{
hasso508e53e2004-05-18 18:57:06 +0000798 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000799 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000800 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
801
hasso6452df02004-08-15 05:52:07 +0000802 install_element (OSPF6_NODE, &area_range_cmd);
803 install_element (OSPF6_NODE, &area_range_advertise_cmd);
804 install_element (OSPF6_NODE, &no_area_range_cmd);
hasso34956b32005-06-24 08:44:02 +0000805
806 install_element (OSPF6_NODE, &area_import_list_cmd);
807 install_element (OSPF6_NODE, &no_area_import_list_cmd);
808 install_element (OSPF6_NODE, &area_export_list_cmd);
809 install_element (OSPF6_NODE, &no_area_export_list_cmd);
810
811 install_element (OSPF6_NODE, &area_filter_list_cmd);
812 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
813
paul718e3742002-12-13 20:15:29 +0000814}
hasso049207c2004-08-04 20:02:13 +0000815
hasso6452df02004-08-15 05:52:07 +0000816