]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_area.c
Merge pull request #818 from donaldsharp/eigrp_afi
[mirror_frr.git] / ospf6d / ospf6_area.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "memory.h"
25 #include "linklist.h"
26 #include "thread.h"
27 #include "vty.h"
28 #include "command.h"
29 #include "if.h"
30 #include "prefix.h"
31 #include "table.h"
32 #include "plist.h"
33 #include "filter.h"
34
35 #include "ospf6_proto.h"
36 #include "ospf6_lsa.h"
37 #include "ospf6_lsdb.h"
38 #include "ospf6_route.h"
39 #include "ospf6_spf.h"
40 #include "ospf6_top.h"
41 #include "ospf6_area.h"
42 #include "ospf6_interface.h"
43 #include "ospf6_intra.h"
44 #include "ospf6_abr.h"
45 #include "ospf6_asbr.h"
46 #include "ospf6d.h"
47
48 int
49 ospf6_area_cmp (void *va, void *vb)
50 {
51 struct ospf6_area *oa = (struct ospf6_area *) va;
52 struct ospf6_area *ob = (struct ospf6_area *) vb;
53 return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
54 }
55
56 /* schedule routing table recalculation */
57 static void
58 ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
59 {
60 switch (ntohs (lsa->header->type))
61 {
62 case OSPF6_LSTYPE_ROUTER:
63 case OSPF6_LSTYPE_NETWORK:
64 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
65 {
66 zlog_debug ("Examin %s", lsa->name);
67 zlog_debug ("Schedule SPF Calculation for %s",
68 OSPF6_AREA (lsa->lsdb->data)->name);
69 }
70 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
71 ospf6_lsadd_to_spf_reason(lsa));
72 break;
73
74 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:
80 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
81 break;
82
83 default:
84 break;
85 }
86 }
87
88 static void
89 ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
90 {
91 switch (ntohs (lsa->header->type))
92 {
93 case OSPF6_LSTYPE_ROUTER:
94 case OSPF6_LSTYPE_NETWORK:
95 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
96 {
97 zlog_debug ("LSA disappearing: %s", lsa->name);
98 zlog_debug ("Schedule SPF Calculation for %s",
99 OSPF6_AREA (lsa->lsdb->data)->name);
100 }
101 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
102 ospf6_lsremove_to_spf_reason(lsa));
103 break;
104
105 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:
111 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
112 break;
113
114 default:
115 break;
116 }
117 }
118
119 static void
120 ospf6_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
126 static void
127 ospf6_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);
134 }
135
136 static void
137 ospf6_area_stub_update (struct ospf6_area *area)
138 {
139
140 if (IS_AREA_STUB (area))
141 {
142 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
143 zlog_debug ("Stubbing out area for if %s\n", area->name);
144 OSPF6_OPT_CLEAR (area->options, OSPF6_OPT_E);
145 }
146 else if (IS_AREA_ENABLED (area))
147 {
148 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
149 zlog_debug ("Normal area for if %s\n", area->name);
150 OSPF6_OPT_SET (area->options, OSPF6_OPT_E);
151 ospf6_asbr_send_externals_to_area (area);
152 }
153
154 OSPF6_ROUTER_LSA_SCHEDULE(area);
155 }
156
157 static int
158 ospf6_area_stub_set (struct ospf6 *ospf6, struct ospf6_area *area)
159 {
160 if (!IS_AREA_STUB(area))
161 {
162 SET_FLAG (area->flag, OSPF6_AREA_STUB);
163 ospf6_area_stub_update (area);
164 }
165
166 return (1);
167 }
168
169 static void
170 ospf6_area_stub_unset (struct ospf6 *ospf6, struct ospf6_area *area)
171 {
172 if (IS_AREA_STUB (area))
173 {
174 UNSET_FLAG (area->flag, OSPF6_AREA_STUB);
175 ospf6_area_stub_update (area);
176 }
177 }
178
179 static void
180 ospf6_area_no_summary_set (struct ospf6 *ospf6, struct ospf6_area *area)
181 {
182 if (area)
183 {
184 if (!area->no_summary)
185 {
186 area->no_summary = 1;
187 ospf6_abr_range_reset_cost (ospf6);
188 ospf6_abr_prefix_resummarize (ospf6);
189 }
190 }
191 }
192
193 static void
194 ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area)
195 {
196 if (area)
197 {
198 if (area->no_summary)
199 {
200 area->no_summary = 0;
201 ospf6_abr_range_reset_cost (ospf6);
202 ospf6_abr_prefix_resummarize (ospf6);
203 }
204 }
205 }
206
207 /**
208 * Make new area structure.
209 *
210 * @param area_id - ospf6 area ID
211 * @param o - ospf6 instance
212 * @param df - display format for area ID
213 */
214 struct ospf6_area *
215 ospf6_area_create (u_int32_t area_id, struct ospf6 *o, int df)
216 {
217 struct ospf6_area *oa;
218
219 oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
220
221 switch (df)
222 {
223 case OSPF6_AREA_FMT_DECIMAL:
224 snprintf (oa->name, sizeof (oa->name), "%u", ntohl (area_id));
225 break;
226 default:
227 case OSPF6_AREA_FMT_DOTTEDQUAD:
228 inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
229 break;
230 }
231
232 oa->area_id = area_id;
233 oa->if_list = list_new ();
234
235 oa->lsdb = ospf6_lsdb_create (oa);
236 oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
237 oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
238 oa->lsdb_self = ospf6_lsdb_create (oa);
239
240 oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
241 oa->spf_table->scope = oa;
242 oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
243 oa->route_table->scope = oa;
244 oa->route_table->hook_add = ospf6_area_route_hook_add;
245 oa->route_table->hook_remove = ospf6_area_route_hook_remove;
246
247 oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
248 oa->range_table->scope = oa;
249 bf_init(oa->range_table->idspace, 32);
250 oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
251 oa->summary_prefix->scope = oa;
252 oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
253 oa->summary_router->scope = oa;
254
255 /* set default options */
256 if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
257 {
258 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
259 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
260 }
261 else
262 {
263 OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
264 OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
265 }
266
267 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
268
269 SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE);
270 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
271
272 oa->ospf6 = o;
273 listnode_add_sort (o->area_list, oa);
274
275 if (area_id == OSPF_AREA_BACKBONE)
276 {
277 o->backbone = oa;
278 }
279
280 return oa;
281 }
282
283 void
284 ospf6_area_delete (struct ospf6_area *oa)
285 {
286 struct listnode *n;
287 struct ospf6_interface *oi;
288
289 /* The ospf6_interface structs store configuration
290 * information which should not be lost/reset when
291 * deleting an area.
292 * So just detach the interface from the area and
293 * keep it around. */
294 for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
295 oi->area = NULL;
296
297 list_delete (oa->if_list);
298
299 ospf6_lsdb_delete (oa->lsdb);
300 ospf6_lsdb_delete (oa->lsdb_self);
301
302 ospf6_spf_table_finish (oa->spf_table);
303 ospf6_route_table_delete (oa->spf_table);
304 ospf6_route_table_delete (oa->route_table);
305
306 ospf6_route_table_delete (oa->range_table);
307 ospf6_route_table_delete (oa->summary_prefix);
308 ospf6_route_table_delete (oa->summary_router);
309
310 listnode_delete (oa->ospf6->area_list, oa);
311 oa->ospf6 = NULL;
312
313 /* free area */
314 XFREE (MTYPE_OSPF6_AREA, oa);
315 }
316
317 struct ospf6_area *
318 ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
319 {
320 struct ospf6_area *oa;
321 struct listnode *n;
322
323 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
324 if (oa->area_id == area_id)
325 return oa;
326
327 return (struct ospf6_area *) NULL;
328 }
329
330 void
331 ospf6_area_enable (struct ospf6_area *oa)
332 {
333 struct listnode *node, *nnode;
334 struct ospf6_interface *oi;
335
336 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
337
338 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
339 ospf6_interface_enable (oi);
340 ospf6_abr_enable_area (oa);
341 }
342
343 void
344 ospf6_area_disable (struct ospf6_area *oa)
345 {
346 struct listnode *node, *nnode;
347 struct ospf6_interface *oi;
348
349 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
350
351 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
352 ospf6_interface_disable (oi);
353
354 ospf6_abr_disable_area (oa);
355 ospf6_lsdb_remove_all (oa->lsdb);
356 ospf6_lsdb_remove_all (oa->lsdb_self);
357
358 ospf6_spf_table_finish(oa->spf_table);
359 ospf6_route_remove_all(oa->route_table);
360
361 THREAD_OFF (oa->thread_router_lsa);
362 THREAD_OFF (oa->thread_intra_prefix_lsa);
363 }
364
365
366 void
367 ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
368 {
369 struct listnode *i;
370 struct ospf6_interface *oi;
371 unsigned long result;
372
373 if (!IS_AREA_STUB (oa))
374 vty_out (vty, " Area %s\n", oa->name);
375 else
376 {
377 if (oa->no_summary)
378 {
379 vty_out (vty, " Area %s[Stub, No Summary]\n", oa->name);
380 }
381 else
382 {
383 vty_out (vty, " Area %s[Stub]\n", oa->name);
384 }
385 }
386 vty_out (vty, " Number of Area scoped LSAs is %u\n",
387 oa->lsdb->count);
388
389 vty_out (vty, " Interface attached to this area:");
390 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
391 vty_out (vty, " %s", oi->interface->name);
392 vty_out (vty, "\n");
393
394 if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec)
395 {
396 result = monotime_since(&oa->ts_spf, NULL);
397 if (result/TIMER_SECOND_MICRO > 0)
398 {
399 vty_out (vty, "SPF last executed %ld.%lds ago\n",
400 result/TIMER_SECOND_MICRO,
401 result % TIMER_SECOND_MICRO);
402 }
403 else
404 {
405 vty_out (vty, "SPF last executed %ldus ago\n",
406 result);
407 }
408 }
409 else
410 vty_out (vty, "SPF has not been run\n");
411 }
412
413
414 #define OSPF6_CMD_AREA_GET(str, oa) \
415 { \
416 char *ep; \
417 u_int32_t area_id = htonl (strtoul (str, &ep, 10)); \
418 if (*ep && inet_pton (AF_INET, str, &area_id) != 1) \
419 { \
420 vty_out (vty, "Malformed Area-ID: %s\n", str); \
421 return CMD_SUCCESS; \
422 } \
423 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL : \
424 OSPF6_AREA_FMT_DOTTEDQUAD; \
425 oa = ospf6_area_lookup (area_id, ospf6); \
426 if (oa == NULL) \
427 oa = ospf6_area_create (area_id, ospf6, format); \
428 }
429
430 DEFUN (area_range,
431 area_range_cmd,
432 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
433 "OSPF6 area parameters\n"
434 "OSPF6 area ID in IP address format\n"
435 "OSPF6 area ID as a decimal value\n"
436 "Configured address range\n"
437 "Specify IPv6 prefix\n"
438 "Advertise\n"
439 "Do not advertise\n"
440 "User specified metric for this range\n"
441 "Advertised metric for this range\n")
442 {
443 int idx_ipv4 = 1;
444 int idx_ipv6_prefixlen = 3;
445 int idx_type = 4;
446 int ret;
447 struct ospf6_area *oa;
448 struct prefix prefix;
449 struct ospf6_route *range;
450 u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
451
452 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
453
454 ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &prefix);
455 if (ret != 1 || prefix.family != AF_INET6)
456 {
457 vty_out (vty, "Malformed argument: %s\n", argv[idx_ipv6_prefixlen]->arg);
458 return CMD_SUCCESS;
459 }
460
461 range = ospf6_route_lookup (&prefix, oa->range_table);
462 if (range == NULL)
463 {
464 range = ospf6_route_create ();
465 range->type = OSPF6_DEST_TYPE_RANGE;
466 range->prefix = prefix;
467 range->path.area_id = oa->area_id;
468 range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
469 }
470
471 if (argc > idx_type)
472 {
473 if (strmatch (argv[idx_type]->text, "not-advertise"))
474 {
475 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
476 }
477 else if (strmatch (argv[idx_type]->text, "advertise"))
478 {
479 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
480 }
481 else
482 {
483 cost = strtoul(argv[5]->arg, NULL, 10);
484 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
485 }
486 }
487
488 range->path.u.cost_config = cost;
489
490 zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag);
491 if (range->rnode == NULL)
492 {
493 ospf6_route_add (range, oa->range_table);
494 }
495
496 if (ospf6_is_router_abr (ospf6))
497 {
498 /* Redo summaries if required */
499 ospf6_abr_prefix_resummarize (ospf6);
500 }
501
502 return CMD_SUCCESS;
503 }
504
505 DEFUN (no_area_range,
506 no_area_range_cmd,
507 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
508 NO_STR
509 "OSPF6 area parameters\n"
510 "OSPF6 area ID in IP address format\n"
511 "OSPF6 area ID as a decimal value\n"
512 "Configured address range\n"
513 "Specify IPv6 prefix\n"
514 "Advertise\n"
515 "Do not advertise\n"
516 "User specified metric for this range\n"
517 "Advertised metric for this range\n")
518 {
519 int idx_ipv4 = 2;
520 int idx_ipv6 = 4;
521 int ret;
522 struct ospf6_area *oa;
523 struct prefix prefix;
524 struct ospf6_route *range, *route;
525
526 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
527
528 ret = str2prefix (argv[idx_ipv6]->arg, &prefix);
529 if (ret != 1 || prefix.family != AF_INET6)
530 {
531 vty_out (vty, "Malformed argument: %s\n", argv[idx_ipv6]->arg);
532 return CMD_SUCCESS;
533 }
534
535 range = ospf6_route_lookup (&prefix, oa->range_table);
536 if (range == NULL)
537 {
538 vty_out (vty, "Range %s does not exists.\n", argv[idx_ipv6]->arg);
539 return CMD_SUCCESS;
540 }
541
542 if (ospf6_is_router_abr(oa->ospf6))
543 {
544 /* Blow away the aggregated LSA and route */
545 SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
546
547 /* Redo summaries if required */
548 for (route = ospf6_route_head (ospf6->route_table); route;
549 route = ospf6_route_next (route))
550 ospf6_abr_originate_summary(route);
551
552 /* purge the old aggregated summary LSA */
553 ospf6_abr_originate_summary(range);
554 }
555 ospf6_route_remove (range, oa->range_table);
556
557 return CMD_SUCCESS;
558 }
559
560 void
561 ospf6_area_config_write (struct vty *vty)
562 {
563 struct listnode *node;
564 struct ospf6_area *oa;
565 struct ospf6_route *range;
566 char buf[PREFIX2STR_BUFFER];
567
568 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
569 {
570 for (range = ospf6_route_head (oa->range_table); range;
571 range = ospf6_route_next (range))
572 {
573 prefix2str (&range->prefix, buf, sizeof (buf));
574 vty_out (vty, " area %s range %s", oa->name, buf);
575
576 if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
577 {
578 vty_out (vty, " not-advertise");
579 }
580 else
581 {
582 // "advertise" is the default so we do not display it
583 if (range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
584 vty_out (vty, " cost %d", range->path.u.cost_config);
585 }
586 vty_out (vty, "\n");
587
588 }
589 if (IS_AREA_STUB (oa))
590 {
591 if (oa->no_summary)
592 vty_out (vty, " area %s stub no-summary\n", oa->name);
593 else
594 vty_out (vty, " area %s stub\n", oa->name);
595 }
596 if (PREFIX_NAME_IN (oa))
597 vty_out (vty, " area %s filter-list prefix %s in\n",
598 oa->name, PREFIX_NAME_IN (oa));
599 if (PREFIX_NAME_OUT (oa))
600 vty_out (vty, " area %s filter-list prefix %s out\n",
601 oa->name, PREFIX_NAME_OUT (oa));
602 if (IMPORT_NAME (oa))
603 vty_out (vty, " area %s import-list %s\n",
604 oa->name, IMPORT_NAME (oa));
605 if (EXPORT_NAME (oa))
606 vty_out (vty, " area %s export-list %s\n",
607 oa->name, EXPORT_NAME (oa));
608 }
609 }
610
611 DEFUN (area_filter_list,
612 area_filter_list_cmd,
613 "area A.B.C.D filter-list prefix WORD <in|out>",
614 "OSPF6 area parameters\n"
615 "OSPF6 area ID in IP address format\n"
616 "Filter networks between OSPF6 areas\n"
617 "Filter prefixes between OSPF6 areas\n"
618 "Name of an IPv6 prefix-list\n"
619 "Filter networks sent to this area\n"
620 "Filter networks sent from this area\n")
621 {
622 char *inout = argv[argc - 1]->text;
623 char *areaid = argv[1]->arg;
624 char *plistname = argv[4]->arg;
625
626 struct ospf6_area *area;
627 struct prefix_list *plist;
628
629 OSPF6_CMD_AREA_GET (areaid, area);
630
631 plist = prefix_list_lookup (AFI_IP6, plistname);
632 if (strmatch (inout, "in"))
633 {
634 PREFIX_LIST_IN (area) = plist;
635 if (PREFIX_NAME_IN (area))
636 free (PREFIX_NAME_IN (area));
637
638 PREFIX_NAME_IN (area) = strdup (plistname);
639 ospf6_abr_reimport (area);
640 }
641 else
642 {
643 PREFIX_LIST_OUT (area) = plist;
644 if (PREFIX_NAME_OUT (area))
645 free (PREFIX_NAME_OUT (area));
646
647 PREFIX_NAME_OUT (area) = strdup (plistname);
648 ospf6_abr_enable_area (area);
649 }
650
651 return CMD_SUCCESS;
652 }
653
654 DEFUN (no_area_filter_list,
655 no_area_filter_list_cmd,
656 "no area A.B.C.D filter-list prefix WORD <in|out>",
657 NO_STR
658 "OSPF6 area parameters\n"
659 "OSPF6 area ID in IP address format\n"
660 "Filter networks between OSPF6 areas\n"
661 "Filter prefixes between OSPF6 areas\n"
662 "Name of an IPv6 prefix-list\n"
663 "Filter networks sent to this area\n"
664 "Filter networks sent from this area\n")
665 {
666 char *inout = argv[argc - 1]->text;
667 char *areaid = argv[2]->arg;
668 char *plistname = argv[5]->arg;
669
670 struct ospf6_area *area;
671
672 OSPF6_CMD_AREA_GET (areaid, area);
673
674 if (strmatch (inout, "in"))
675 {
676 if (PREFIX_NAME_IN (area))
677 if (!strmatch (PREFIX_NAME_IN (area), plistname))
678 return CMD_SUCCESS;
679
680 PREFIX_LIST_IN (area) = NULL;
681 if (PREFIX_NAME_IN (area))
682 free (PREFIX_NAME_IN (area));
683
684 PREFIX_NAME_IN (area) = NULL;
685 ospf6_abr_reimport (area);
686 }
687 else
688 {
689 if (PREFIX_NAME_OUT (area))
690 if (!strmatch (PREFIX_NAME_OUT (area), plistname))
691 return CMD_SUCCESS;
692
693 PREFIX_LIST_OUT (area) = NULL;
694 if (PREFIX_NAME_OUT (area))
695 free (PREFIX_NAME_OUT (area));
696
697 PREFIX_NAME_OUT (area) = NULL;
698 ospf6_abr_enable_area (area);
699 }
700
701 return CMD_SUCCESS;
702 }
703
704 DEFUN (area_import_list,
705 area_import_list_cmd,
706 "area A.B.C.D import-list NAME",
707 "OSPF6 area parameters\n"
708 "OSPF6 area ID in IP address format\n"
709 "Set the filter for networks from other areas announced to the specified one\n"
710 "Name of the acess-list\n")
711 {
712 int idx_ipv4 = 1;
713 int idx_name = 3;
714 struct ospf6_area *area;
715 struct access_list *list;
716
717 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
718
719 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
720
721 IMPORT_LIST (area) = list;
722
723 if (IMPORT_NAME (area))
724 free (IMPORT_NAME (area));
725
726 IMPORT_NAME (area) = strdup (argv[idx_name]->arg);
727 ospf6_abr_reimport (area);
728
729 return CMD_SUCCESS;
730 }
731
732 DEFUN (no_area_import_list,
733 no_area_import_list_cmd,
734 "no area A.B.C.D import-list NAME",
735 NO_STR
736 "OSPF6 area parameters\n"
737 "OSPF6 area ID in IP address format\n"
738 "Unset the filter for networks announced to other areas\n"
739 "Name of the access-list\n")
740 {
741 int idx_ipv4 = 2;
742 struct ospf6_area *area;
743
744 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
745
746 IMPORT_LIST (area) = 0;
747
748 if (IMPORT_NAME (area))
749 free (IMPORT_NAME (area));
750
751 IMPORT_NAME (area) = NULL;
752 ospf6_abr_reimport (area);
753
754 return CMD_SUCCESS;
755 }
756
757 DEFUN (area_export_list,
758 area_export_list_cmd,
759 "area A.B.C.D export-list NAME",
760 "OSPF6 area parameters\n"
761 "OSPF6 area ID in IP address format\n"
762 "Set the filter for networks announced to other areas\n"
763 "Name of the acess-list\n")
764 {
765 int idx_ipv4 = 1;
766 int idx_name = 3;
767 struct ospf6_area *area;
768 struct access_list *list;
769
770 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
771
772 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
773
774 EXPORT_LIST (area) = list;
775
776 if (EXPORT_NAME (area))
777 free (EXPORT_NAME (area));
778
779 EXPORT_NAME (area) = strdup (argv[idx_name]->arg);
780 ospf6_abr_enable_area (area);
781
782 return CMD_SUCCESS;
783 }
784
785 DEFUN (no_area_export_list,
786 no_area_export_list_cmd,
787 "no area A.B.C.D export-list NAME",
788 NO_STR
789 "OSPF6 area parameters\n"
790 "OSPF6 area ID in IP address format\n"
791 "Unset the filter for networks announced to other areas\n"
792 "Name of the access-list\n")
793 {
794 int idx_ipv4 = 2;
795 struct ospf6_area *area;
796
797 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
798
799 EXPORT_LIST (area) = 0;
800
801 if (EXPORT_NAME (area))
802 free (EXPORT_NAME (area));
803
804 EXPORT_NAME (area) = NULL;
805 ospf6_abr_enable_area (area);
806
807 return CMD_SUCCESS;
808 }
809
810 DEFUN (show_ipv6_ospf6_spf_tree,
811 show_ipv6_ospf6_spf_tree_cmd,
812 "show ipv6 ospf6 spf tree",
813 SHOW_STR
814 IP6_STR
815 OSPF6_STR
816 "Shortest Path First caculation\n"
817 "Show SPF tree\n")
818 {
819 struct listnode *node;
820 struct ospf6_area *oa;
821 struct ospf6_vertex *root;
822 struct ospf6_route *route;
823 struct prefix prefix;
824
825 OSPF6_CMD_CHECK_RUNNING ();
826
827 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
828
829 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
830 {
831 route = ospf6_route_lookup (&prefix, oa->spf_table);
832 if (route == NULL)
833 {
834 vty_out (vty, "LS entry for root not found in area %s\n",
835 oa->name);
836 continue;
837 }
838 root = (struct ospf6_vertex *) route->route_option;
839 ospf6_spf_display_subtree (vty, "", 0, root);
840 }
841
842 return CMD_SUCCESS;
843 }
844
845 DEFUN (show_ipv6_ospf6_area_spf_tree,
846 show_ipv6_ospf6_area_spf_tree_cmd,
847 "show ipv6 ospf6 area A.B.C.D spf tree",
848 SHOW_STR
849 IP6_STR
850 OSPF6_STR
851 OSPF6_AREA_STR
852 OSPF6_AREA_ID_STR
853 "Shortest Path First caculation\n"
854 "Show SPF tree\n")
855 {
856 int idx_ipv4 = 4;
857 u_int32_t area_id;
858 struct ospf6_area *oa;
859 struct ospf6_vertex *root;
860 struct ospf6_route *route;
861 struct prefix prefix;
862
863 OSPF6_CMD_CHECK_RUNNING ();
864
865 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
866
867 if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
868 {
869 vty_out (vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
870 return CMD_SUCCESS;
871 }
872 oa = ospf6_area_lookup (area_id, ospf6);
873 if (oa == NULL)
874 {
875 vty_out (vty, "No such Area: %s\n", argv[idx_ipv4]->arg);
876 return CMD_SUCCESS;
877 }
878
879 route = ospf6_route_lookup (&prefix, oa->spf_table);
880 if (route == NULL)
881 {
882 vty_out (vty, "LS entry for root not found in area %s\n",
883 oa->name);
884 return CMD_SUCCESS;
885 }
886 root = (struct ospf6_vertex *) route->route_option;
887 ospf6_spf_display_subtree (vty, "", 0, root);
888
889 return CMD_SUCCESS;
890 }
891
892 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
893 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
894 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
895 SHOW_STR
896 IP6_STR
897 OSPF6_STR
898 "Shortest Path First calculation\n"
899 "Show SPF tree\n"
900 "Specify root's router-id to calculate another router's SPF tree\n"
901 "OSPF6 area parameters\n"
902 OSPF6_AREA_ID_STR)
903 {
904 int idx_ipv4 = 5;
905 int idx_ipv4_2 = 7;
906 u_int32_t area_id;
907 struct ospf6_area *oa;
908 struct ospf6_vertex *root;
909 struct ospf6_route *route;
910 struct prefix prefix;
911 u_int32_t router_id;
912 struct ospf6_route_table *spf_table;
913 unsigned char tmp_debug_ospf6_spf = 0;
914
915 OSPF6_CMD_CHECK_RUNNING ();
916
917 inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
918 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
919
920 if (inet_pton (AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1)
921 {
922 vty_out (vty, "Malformed Area-ID: %s\n", argv[idx_ipv4_2]->arg);
923 return CMD_SUCCESS;
924 }
925 oa = ospf6_area_lookup (area_id, ospf6);
926 if (oa == NULL)
927 {
928 vty_out (vty, "No such Area: %s\n", argv[idx_ipv4_2]->arg);
929 return CMD_SUCCESS;
930 }
931
932 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
933 conf_debug_ospf6_spf = 0;
934
935 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
936 ospf6_spf_calculation (router_id, spf_table, oa);
937
938 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
939
940 route = ospf6_route_lookup (&prefix, spf_table);
941 if (route == NULL)
942 {
943 ospf6_spf_table_finish (spf_table);
944 ospf6_route_table_delete (spf_table);
945 return CMD_SUCCESS;
946 }
947 root = (struct ospf6_vertex *) route->route_option;
948 ospf6_spf_display_subtree (vty, "", 0, root);
949
950 ospf6_spf_table_finish (spf_table);
951 ospf6_route_table_delete (spf_table);
952
953 return CMD_SUCCESS;
954 }
955
956 DEFUN (ospf6_area_stub,
957 ospf6_area_stub_cmd,
958 "area <A.B.C.D|(0-4294967295)> stub",
959 "OSPF6 area parameters\n"
960 "OSPF6 area ID in IP address format\n"
961 "OSPF6 area ID as a decimal value\n"
962 "Configure OSPF6 area as stub\n")
963 {
964 int idx_ipv4_number = 1;
965 struct ospf6_area *area;
966
967 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
968
969 if (!ospf6_area_stub_set (ospf6, area))
970 {
971 vty_out (vty,"First deconfigure all virtual link through this area\n");
972 return CMD_WARNING_CONFIG_FAILED;
973 }
974
975 ospf6_area_no_summary_unset (ospf6, area);
976
977 return CMD_SUCCESS;
978 }
979
980 DEFUN (ospf6_area_stub_no_summary,
981 ospf6_area_stub_no_summary_cmd,
982 "area <A.B.C.D|(0-4294967295)> stub no-summary",
983 "OSPF6 stub parameters\n"
984 "OSPF6 area ID in IP address format\n"
985 "OSPF6 area ID as a decimal value\n"
986 "Configure OSPF6 area as stub\n"
987 "Do not inject inter-area routes into stub\n")
988 {
989 int idx_ipv4_number = 1;
990 struct ospf6_area *area;
991
992 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
993
994 if (!ospf6_area_stub_set (ospf6, area))
995 {
996 vty_out (vty,"First deconfigure all virtual link through this area\n");
997 return CMD_WARNING_CONFIG_FAILED;
998 }
999
1000 ospf6_area_no_summary_set (ospf6, area);
1001
1002 return CMD_SUCCESS;
1003 }
1004
1005 DEFUN (no_ospf6_area_stub,
1006 no_ospf6_area_stub_cmd,
1007 "no area <A.B.C.D|(0-4294967295)> stub",
1008 NO_STR
1009 "OSPF6 area parameters\n"
1010 "OSPF6 area ID in IP address format\n"
1011 "OSPF6 area ID as a decimal value\n"
1012 "Configure OSPF6 area as stub\n")
1013 {
1014 int idx_ipv4_number = 2;
1015 struct ospf6_area *area;
1016
1017 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
1018
1019 ospf6_area_stub_unset (ospf6, area);
1020 ospf6_area_no_summary_unset (ospf6, area);
1021
1022 return CMD_SUCCESS;
1023 }
1024
1025 DEFUN (no_ospf6_area_stub_no_summary,
1026 no_ospf6_area_stub_no_summary_cmd,
1027 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1028 NO_STR
1029 "OSPF6 area parameters\n"
1030 "OSPF6 area ID in IP address format\n"
1031 "OSPF6 area ID as a decimal value\n"
1032 "Configure OSPF6 area as stub\n"
1033 "Do not inject inter-area routes into area\n")
1034 {
1035 int idx_ipv4_number = 2;
1036 struct ospf6_area *area;
1037
1038 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
1039
1040 ospf6_area_stub_unset (ospf6, area);
1041 ospf6_area_no_summary_unset (ospf6, area);
1042
1043 return CMD_SUCCESS;
1044 }
1045
1046 void
1047 ospf6_area_init (void)
1048 {
1049 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
1050 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
1051 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
1052
1053 install_element (OSPF6_NODE, &area_range_cmd);
1054 install_element (OSPF6_NODE, &no_area_range_cmd);
1055 install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
1056 install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
1057 install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
1058 install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
1059
1060
1061 install_element (OSPF6_NODE, &area_import_list_cmd);
1062 install_element (OSPF6_NODE, &no_area_import_list_cmd);
1063 install_element (OSPF6_NODE, &area_export_list_cmd);
1064 install_element (OSPF6_NODE, &no_area_export_list_cmd);
1065
1066 install_element (OSPF6_NODE, &area_filter_list_cmd);
1067 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
1068
1069 }
1070
1071