]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_redist.c
convert <1-255> to (1-255), ()s to <>s, etc
[mirror_frr.git] / isisd / isis_redist.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_redist.c
3 *
4 * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
5 *
6 * This program 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 Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "if.h"
25 #include "linklist.h"
26 #include "memory.h"
27 #include "isis_memory.h"
28 #include "prefix.h"
29 #include "routemap.h"
30 #include "stream.h"
31 #include "table.h"
32 #include "vty.h"
33
34 #include "isisd/dict.h"
35 #include "isisd/isis_constants.h"
36 #include "isisd/isis_common.h"
37 #include "isisd/isis_flags.h"
38 #include "isisd/isis_misc.h"
39 #include "isisd/isis_circuit.h"
40 #include "isisd/isis_tlv.h"
41 #include "isisd/isisd.h"
42 #include "isisd/isis_lsp.h"
43 #include "isisd/isis_route.h"
44 #include "isisd/isis_zebra.h"
45
46 static int
47 redist_protocol(int family)
48 {
49 if (family == AF_INET)
50 return 0;
51 if (family == AF_INET6)
52 return 1;
53
54 assert(!"Unsupported address family!");
55 }
56
57 static int
58 is_default(struct prefix *p)
59 {
60 if (p->family == AF_INET)
61 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
62 return 1;
63 if (p->family == AF_INET6)
64 if (IN6_IS_ADDR_UNSPECIFIED(&p->u.prefix6) && p->prefixlen == 0)
65 return 1;
66 return 0;
67 }
68
69 static struct route_table*
70 get_ext_info(struct isis *i, int family)
71 {
72 int protocol = redist_protocol(family);
73
74 return i->ext_info[protocol];
75 }
76
77 static struct isis_redist*
78 get_redist_settings(struct isis_area *area, int family, int type, int level)
79 {
80 int protocol = redist_protocol(family);
81
82 return &area->redist_settings[protocol][type][level-1];
83 }
84
85 struct route_table*
86 get_ext_reach(struct isis_area *area, int family, int level)
87 {
88 int protocol = redist_protocol(family);
89
90 return area->ext_reach[protocol][level-1];
91 }
92
93 static struct route_node *
94 isis_redist_route_node_create(route_table_delegate_t *delegate,
95 struct route_table *table)
96 {
97 struct route_node *node;
98 node = XCALLOC(MTYPE_ISIS_EXT_ROUTE, sizeof(*node));
99 return node;
100 }
101
102 static void
103 isis_redist_route_node_destroy(route_table_delegate_t *delegate,
104 struct route_table *table,
105 struct route_node *node)
106 {
107 if (node->info)
108 XFREE(MTYPE_ISIS_EXT_INFO, node->info);
109 XFREE (MTYPE_ISIS_EXT_ROUTE, node);
110 }
111
112 static route_table_delegate_t isis_redist_rt_delegate = {
113 .create_node = isis_redist_route_node_create,
114 .destroy_node = isis_redist_route_node_destroy
115 };
116
117 /* Install external reachability information into a
118 * specific area for a specific level.
119 * Schedule an lsp regenerate if necessary */
120 static void
121 isis_redist_install(struct isis_area *area, int level,
122 struct prefix *p, struct isis_ext_info *info)
123 {
124 int family = p->family;
125 struct route_table *er_table = get_ext_reach(area, family, level);
126 struct route_node *er_node;
127
128 if (!er_table)
129 {
130 zlog_warn("%s: External reachability table of area %s"
131 " is not initialized.", __func__, area->area_tag);
132 return;
133 }
134
135 er_node = route_node_get(er_table, p);
136 if (er_node->info)
137 {
138 route_unlock_node(er_node);
139
140 /* Don't update/reschedule lsp generation if nothing changed. */
141 if (!memcmp(er_node->info, info, sizeof(*info)))
142 return;
143 }
144 else
145 {
146 er_node->info = XMALLOC(MTYPE_ISIS_EXT_INFO, sizeof(*info));
147 }
148
149 memcpy(er_node->info, info, sizeof(*info));
150 lsp_regenerate_schedule(area, level, 0);
151 }
152
153 /* Remove external reachability information from a
154 * specific area for a specific level.
155 * Schedule an lsp regenerate if necessary. */
156 static void
157 isis_redist_uninstall(struct isis_area *area, int level, struct prefix *p)
158 {
159 int family = p->family;
160 struct route_table *er_table = get_ext_reach(area, family, level);
161 struct route_node *er_node;
162
163 if (!er_table)
164 {
165 zlog_warn("%s: External reachability table of area %s"
166 " is not initialized.", __func__, area->area_tag);
167 return;
168 }
169
170 er_node = route_node_lookup(er_table, p);
171 if (!er_node)
172 return;
173 else
174 route_unlock_node(er_node);
175
176 if (!er_node->info)
177 return;
178
179 XFREE(MTYPE_ISIS, er_node->info);
180 route_unlock_node(er_node);
181 lsp_regenerate_schedule(area, level, 0);
182 }
183
184 /* Update external reachability info of area for a given level
185 * and prefix, using the given redistribution settings. */
186 static void
187 isis_redist_update_ext_reach(struct isis_area *area, int level,
188 struct isis_redist *redist, struct prefix *p,
189 struct isis_ext_info *info)
190 {
191 struct isis_ext_info area_info;
192 route_map_result_t map_ret;
193
194 memcpy(&area_info, info, sizeof(area_info));
195 if (redist->metric != 0xffffffff)
196 area_info.metric = redist->metric;
197
198 if (redist->map_name)
199 {
200 map_ret = route_map_apply(redist->map, p, RMAP_ISIS, &area_info);
201 if (map_ret == RMAP_DENYMATCH)
202 area_info.distance = 255;
203 }
204
205 /* Allow synthesized default routes only on always orignate */
206 if (area_info.origin == DEFAULT_ROUTE
207 && redist->redist != DEFAULT_ORIGINATE_ALWAYS)
208 area_info.distance = 255;
209
210 if (area_info.distance < 255)
211 isis_redist_install(area, level, p, &area_info);
212 else
213 isis_redist_uninstall(area, level, p);
214 }
215
216 static void
217 isis_redist_ensure_default(struct isis *isis, int family)
218 {
219 struct prefix p;
220 struct route_table *ei_table = get_ext_info(isis, family);
221 struct route_node *ei_node;
222 struct isis_ext_info *info;
223
224 if (family == AF_INET)
225 {
226 p.family = AF_INET;
227 p.prefixlen = 0;
228 memset(&p.u.prefix4, 0, sizeof(p.u.prefix4));
229 }
230 else if (family == AF_INET6)
231 {
232 p.family = AF_INET6;
233 p.prefixlen = 0;
234 memset(&p.u.prefix6, 0, sizeof(p.u.prefix6));
235 }
236 else
237 assert(!"Unknown family!");
238
239 ei_node = route_node_get(ei_table, &p);
240 if (ei_node->info)
241 {
242 route_unlock_node(ei_node);
243 return;
244 }
245
246 ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info));
247
248 info = ei_node->info;
249 info->origin = DEFAULT_ROUTE;
250 info->distance = 254;
251 info->metric = MAX_WIDE_PATH_METRIC;
252 }
253
254 /* Handle notification about route being added */
255 void
256 isis_redist_add(int type, struct prefix *p, u_char distance, uint32_t metric)
257 {
258 int family = p->family;
259 struct route_table *ei_table = get_ext_info(isis, family);
260 struct route_node *ei_node;
261 struct isis_ext_info *info;
262 struct listnode *node;
263 struct isis_area *area;
264 int level;
265 struct isis_redist *redist;
266
267 char debug_buf[BUFSIZ];
268 prefix2str(p, debug_buf, sizeof(debug_buf));
269
270 zlog_debug("%s: New route %s from %s.", __func__, debug_buf,
271 zebra_route_string(type));
272
273 if (!ei_table)
274 {
275 zlog_warn("%s: External information table not initialized.",
276 __func__);
277 return;
278 }
279
280 ei_node = route_node_get(ei_table, p);
281 if (ei_node->info)
282 route_unlock_node(ei_node);
283 else
284 ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info));
285
286 info = ei_node->info;
287 info->origin = type;
288 info->distance = distance;
289 info->metric = metric;
290
291 if (is_default(p))
292 type = DEFAULT_ROUTE;
293
294 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
295 for (level = 1; level <= ISIS_LEVELS; level++)
296 {
297 redist = get_redist_settings(area, family, type, level);
298 if (!redist->redist)
299 continue;
300
301 isis_redist_update_ext_reach(area, level, redist, p, info);
302 }
303 }
304
305 void
306 isis_redist_delete(int type, struct prefix *p)
307 {
308 int family = p->family;
309 struct route_table *ei_table = get_ext_info(isis, family);
310 struct route_node *ei_node;
311 struct listnode *node;
312 struct isis_area *area;
313 int level;
314 struct isis_redist *redist;
315
316 char debug_buf[BUFSIZ];
317 prefix2str(p, debug_buf, sizeof(debug_buf));
318
319 zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf,
320 zebra_route_string(type));
321
322 if (is_default(p))
323 {
324 /* Don't remove default route but add synthetic route for use
325 * by "default-information originate always". Areas without the
326 * "always" setting will ignore routes with origin DEFAULT_ROUTE. */
327 isis_redist_add(DEFAULT_ROUTE, p, 254, MAX_WIDE_PATH_METRIC);
328 return;
329 }
330
331 if (!ei_table)
332 {
333 zlog_warn("%s: External information table not initialized.",
334 __func__);
335 return;
336 }
337
338 ei_node = route_node_lookup(ei_table, p);
339 if (!ei_node || !ei_node->info)
340 {
341 char buf[BUFSIZ];
342 prefix2str(p, buf, sizeof(buf));
343 zlog_warn("%s: Got a delete for %s route %s, but that route"
344 " was never added.", __func__, zebra_route_string(type),
345 buf);
346 if (ei_node)
347 route_unlock_node(ei_node);
348 return;
349 }
350 route_unlock_node(ei_node);
351
352 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
353 for (level = 1; level < ISIS_LEVELS; level++)
354 {
355 redist = get_redist_settings(area, family, type, level);
356 if (!redist->redist)
357 continue;
358
359 isis_redist_uninstall(area, level, p);
360 }
361
362 XFREE(MTYPE_ISIS, ei_node->info);
363 route_unlock_node(ei_node);
364 }
365
366 static void
367 isis_redist_routemap_set(struct isis_redist *redist, const char *routemap)
368 {
369 if (redist->map_name) {
370 XFREE(MTYPE_ISIS, redist->map_name);
371 redist->map = NULL;
372 }
373
374 if (routemap && strlen(routemap)) {
375 redist->map_name = XSTRDUP(MTYPE_ISIS, routemap);
376 redist->map = route_map_lookup_by_name(routemap);
377 }
378 }
379
380 static void
381 isis_redist_update_zebra_subscriptions(struct isis *isis)
382 {
383 struct listnode *node;
384 struct isis_area *area;
385 int type;
386 int level;
387 int protocol;
388
389 char do_subscribe[ZEBRA_ROUTE_MAX + 1];
390
391 memset(do_subscribe, 0, sizeof(do_subscribe));
392
393 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
394 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
395 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
396 for (level = 0; level < ISIS_LEVELS; level++)
397 if (area->redist_settings[protocol][type][level].redist)
398 do_subscribe[type] = 1;
399
400 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
401 {
402 /* This field is actually controlling transmission of the IS-IS
403 * routes to Zebra and has nothing to do with redistribution,
404 * so skip it. */
405 if (type == ZEBRA_ROUTE_ISIS)
406 continue;
407
408 if (do_subscribe[type])
409 isis_zebra_redistribute_set(type);
410 else
411 isis_zebra_redistribute_unset(type);
412 }
413 }
414
415 static void
416 isis_redist_set(struct isis_area *area, int level,
417 int family, int type, uint32_t metric,
418 const char *routemap, int originate_type)
419 {
420 int protocol = redist_protocol(family);
421 struct isis_redist *redist = get_redist_settings(area, family, type, level);
422 int i;
423 struct route_table *ei_table;
424 struct route_node *rn;
425 struct isis_ext_info *info;
426
427 redist->redist = (type == DEFAULT_ROUTE) ? originate_type : 1;
428 redist->metric = metric;
429 isis_redist_routemap_set(redist, routemap);
430
431 if (!area->ext_reach[protocol][level-1])
432 {
433 area->ext_reach[protocol][level-1] =
434 route_table_init_with_delegate(&isis_redist_rt_delegate);
435 }
436
437 for (i = 0; i < REDIST_PROTOCOL_COUNT; i++)
438 if (!area->isis->ext_info[i])
439 {
440 area->isis->ext_info[i] =
441 route_table_init_with_delegate(&isis_redist_rt_delegate);
442 }
443
444 isis_redist_update_zebra_subscriptions(area->isis);
445
446 if (type == DEFAULT_ROUTE && originate_type == DEFAULT_ORIGINATE_ALWAYS)
447 isis_redist_ensure_default(area->isis, family);
448
449 ei_table = get_ext_info(area->isis, family);
450 for (rn = route_top(ei_table); rn; rn = route_next(rn))
451 {
452 if (!rn->info)
453 continue;
454 info = rn->info;
455
456 if (type == DEFAULT_ROUTE)
457 {
458 if (!is_default(&rn->p))
459 continue;
460 }
461 else
462 {
463 if (info->origin != type)
464 continue;
465 }
466
467 isis_redist_update_ext_reach(area, level, redist, &rn->p, info);
468 }
469 }
470
471 static void
472 isis_redist_unset(struct isis_area *area, int level,
473 int family, int type)
474 {
475 struct isis_redist *redist = get_redist_settings(area, family, type, level);
476 struct route_table *er_table = get_ext_reach(area, family, level);
477 struct route_node *rn;
478 struct isis_ext_info *info;
479
480 if (!redist->redist)
481 return;
482
483 redist->redist = 0;
484 if (!er_table)
485 {
486 zlog_warn("%s: External reachability table uninitialized.", __func__);
487 return;
488 }
489
490 for (rn = route_top(er_table); rn; rn = route_next(rn))
491 {
492 if (!rn->info)
493 continue;
494 info = rn->info;
495
496 if (type == DEFAULT_ROUTE)
497 {
498 if (!is_default(&rn->p))
499 continue;
500 }
501 else
502 {
503 if (info->origin != type)
504 continue;
505 }
506
507 XFREE(MTYPE_ISIS, rn->info);
508 route_unlock_node(rn);
509 }
510
511 lsp_regenerate_schedule(area, level, 0);
512 isis_redist_update_zebra_subscriptions(area->isis);
513 }
514
515 void
516 isis_redist_area_finish(struct isis_area *area)
517 {
518 int protocol;
519 int level;
520 int type;
521
522 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
523 for (level = 0; level < ISIS_LEVELS; level++)
524 {
525 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
526 {
527 struct isis_redist *redist;
528
529 redist = &area->redist_settings[protocol][type][level];
530 redist->redist = 0;
531 if (redist->map_name)
532 XFREE(MTYPE_ISIS, redist->map_name);
533 }
534 route_table_finish(area->ext_reach[protocol][level]);
535 }
536
537 isis_redist_update_zebra_subscriptions(area->isis);
538 }
539
540 DEFUN (isis_redistribute,
541 isis_redistribute_cmd,
542 "redistribute <ipv4|ipv6> " QUAGGA_REDIST_STR_ISISD " <level-1|level-2> [metric (0-16777215)|route-map WORD]",
543 REDIST_STR
544 "Redistribute IPv4 routes\n"
545 "Redistribute IPv6 routes\n"
546 QUAGGA_REDIST_HELP_STR_ISISD
547 "Redistribute into level-1\n"
548 "Redistribute into level-2\n"
549 "Metric for redistributed routes\n"
550 "ISIS default metric\n"
551 "Route map reference\n"
552 "Pointer to route-map entries\n")
553 {
554 struct isis_area *area = vty->index;
555 int family;
556 int afi;
557 int type;
558 int level;
559 unsigned long metric;
560 const char *routemap;
561
562 if (argc < 5)
563 return CMD_WARNING;
564
565 family = str2family(argv[1]->arg);
566 if (family < 0)
567 return CMD_WARNING;
568
569 afi = family2afi(family);
570 if (!afi)
571 return CMD_WARNING;
572
573 type = proto_redistnum(afi, argv[2]->arg);
574 if (type < 0 || type == ZEBRA_ROUTE_ISIS)
575 return CMD_WARNING;
576
577 if (!strcmp("level-1", argv[3]->arg))
578 level = 1;
579 else if (!strcmp("level-2", argv[3]->arg))
580 level = 2;
581 else
582 return CMD_WARNING;
583
584 if ((area->is_type & level) != level)
585 {
586 vty_out(vty, "Node is not a level-%d IS%s", level, VTY_NEWLINE);
587 return CMD_WARNING;
588 }
589
590 if (argv[4]->arg)
591 {
592 char *endp;
593 metric = strtoul(argv[4]->arg, &endp, 10);
594 if (argv[4]->arg[0] == '\0' || *endp != '\0')
595 return CMD_WARNING;
596 }
597 else
598 {
599 metric = 0xffffffff;
600 }
601
602 routemap = argv[4];
603
604 isis_redist_set(area, level, family, type, metric, routemap, 0);
605 return 0;
606 }
607
608 DEFUN (no_isis_redistribute,
609 no_isis_redistribute_cmd,
610 "no redistribute <ipv4|ipv6> " QUAGGA_REDIST_STR_ISISD " <level-1|level-2>",
611 NO_STR
612 REDIST_STR
613 "Redistribute IPv4 routes\n"
614 "Redistribute IPv6 routes\n"
615 QUAGGA_REDIST_HELP_STR_ISISD
616 "Redistribute into level-1\n"
617 "Redistribute into level-2\n")
618 {
619 struct isis_area *area = vty->index;
620 int type;
621 int level;
622 int family;
623 int afi;
624
625 if (argc < 3)
626 return CMD_WARNING;
627
628 family = str2family(argv[2]->arg);
629 if (family < 0)
630 return CMD_WARNING;
631
632 afi = family2afi(family);
633 if (!afi)
634 return CMD_WARNING;
635
636 type = proto_redistnum(afi, argv[3]->arg);
637 if (type < 0 || type == ZEBRA_ROUTE_ISIS)
638 return CMD_WARNING;
639
640 if (!strcmp("level-1", argv[4]->arg))
641 level = 1;
642 else if (!strcmp("level-2", argv[4]->arg))
643 level = 2;
644 else
645 return CMD_WARNING;
646
647 isis_redist_unset(area, level, family, type);
648 return 0;
649 }
650
651 DEFUN (isis_default_originate,
652 isis_default_originate_cmd,
653 "default-information originate <ipv4|ipv6> <level-1|level-2> [always|metric (0-16777215)|route-map WORD]",
654 "Control distribution of default information\n"
655 "Distribute a default route\n"
656 "Distribute default route for IPv4\n"
657 "Distribute default route for IPv6\n"
658 "Distribute default route into level-1\n"
659 "Distribute default route into level-2\n"
660 "Always advertise default route\n"
661 "Metric for default route\n"
662 "ISIS default metric\n"
663 "Route map reference\n"
664 "Pointer to route-map entries\n")
665 {
666 struct isis_area *area = vty->index;
667 int family;
668 int originate_type;
669 int level;
670 unsigned long metric;
671 const char *routemap;
672
673 if (argc < 5)
674 return CMD_WARNING;
675
676 family = str2family(argv[2]->arg);
677 if (family < 0)
678 return CMD_WARNING;
679
680 if (!strcmp("level-1", argv[3]->arg))
681 level = 1;
682 else if (!strcmp("level-2", argv[3]->arg))
683 level = 2;
684 else
685 return CMD_WARNING;
686
687 if ((area->is_type & level) != level)
688 {
689 vty_out(vty, "Node is not a level-%d IS%s", level, VTY_NEWLINE);
690 return CMD_WARNING;
691 }
692
693 if (argv[4]->arg && *argv[4]->arg != '\0')
694 originate_type = DEFAULT_ORIGINATE_ALWAYS;
695 else
696 originate_type = DEFAULT_ORIGINATE;
697
698 if (family == AF_INET6 && originate_type != DEFAULT_ORIGINATE_ALWAYS)
699 {
700 vty_out(vty, "Zebra doesn't implement default-originate for IPv6 yet%s", VTY_NEWLINE);
701 vty_out(vty, "so use with care or use default-originate always.%s", VTY_NEWLINE);
702 }
703
704 if (argv[3])
705 {
706 char *endp;
707 metric = strtoul(argv[3], &endp, 10);
708 if (argv[3][0] == '\0' || *endp != '\0')
709 return CMD_WARNING;
710 }
711 else
712 {
713 metric = 0xffffffff;
714 }
715
716 routemap = argv[4];
717
718 isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap, originate_type);
719 return 0;
720 }
721
722 DEFUN (no_isis_default_originate,
723 no_isis_default_originate_cmd,
724 "no default-information originate <ipv4|ipv6> <level-1|level-2>",
725 NO_STR
726 "Control distribution of default information\n"
727 "Distribute a default route\n"
728 "Distribute default route for IPv4\n"
729 "Distribute default route for IPv6\n"
730 "Distribute default route into level-1\n"
731 "Distribute default route into level-2\n")
732 {
733 struct isis_area *area = vty->index;
734
735 int family;
736 int level;
737
738 if (argc < 2)
739 return CMD_WARNING;
740
741 family = str2family(argv[3]->arg);
742 if (family < 0)
743 return CMD_WARNING;
744
745 if (!strcmp("level-1", argv[4]->arg))
746 level = 1;
747 else if (!strcmp("level-2", argv[4]->arg))
748 level = 2;
749 else
750 return CMD_WARNING;
751
752 isis_redist_unset(area, level, family, DEFAULT_ROUTE);
753 return 0;
754 }
755
756 int
757 isis_redist_config_write(struct vty *vty, struct isis_area *area,
758 int family)
759 {
760 int type;
761 int level;
762 int write = 0;
763 struct isis_redist *redist;
764 const char *family_str;
765
766 if (family == AF_INET)
767 family_str = "ipv4";
768 else if (family == AF_INET6)
769 family_str = "ipv6";
770 else
771 return 0;
772
773 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
774 {
775 if (type == ZEBRA_ROUTE_ISIS)
776 continue;
777
778 for (level = 1; level <= ISIS_LEVELS; level++)
779 {
780 redist = get_redist_settings(area, family, type, level);
781 if (!redist->redist)
782 continue;
783 vty_out(vty, " redistribute %s %s level-%d",
784 family_str, zebra_route_string(type), level);
785 if (redist->metric != 0xffffffff)
786 vty_out(vty, " metric %u", redist->metric);
787 if (redist->map_name)
788 vty_out(vty, " route-map %s", redist->map_name);
789 vty_out(vty, "%s", VTY_NEWLINE);
790 write++;
791 }
792 }
793
794 for (level = 1; level <= ISIS_LEVELS; level++)
795 {
796 redist = get_redist_settings(area, family, DEFAULT_ROUTE, level);
797 if (!redist->redist)
798 continue;
799 vty_out(vty, " default-information originate %s level-%d",
800 family_str, level);
801 if (redist->redist == DEFAULT_ORIGINATE_ALWAYS)
802 vty_out(vty, " always");
803 if (redist->metric != 0xffffffff)
804 vty_out(vty, " metric %u", redist->metric);
805 if (redist->map_name)
806 vty_out(vty, " route-map %s", redist->map_name);
807 vty_out(vty, "%s", VTY_NEWLINE);
808 write++;
809 }
810
811 return write;
812 }
813
814 void
815 isis_redist_init(void)
816 {
817 install_element(ISIS_NODE, &isis_redistribute_cmd);
818 install_element(ISIS_NODE, &no_isis_redistribute_cmd);
819 install_element(ISIS_NODE, &isis_default_originate_cmd);
820 install_element(ISIS_NODE, &no_isis_default_originate_cmd);
821 }