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