]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isisd.c
Merge pull request #8950 from idryzhov/ospf6-router-id
[mirror_frr.git] / isisd / isisd.c
1 /*
2 * IS-IS Rout(e)ing protocol - isisd.c
3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <zebra.h>
24
25 #include "thread.h"
26 #include "vty.h"
27 #include "command.h"
28 #include "log.h"
29 #include "memory.h"
30 #include "time.h"
31 #include "linklist.h"
32 #include "if.h"
33 #include "hash.h"
34 #include "filter.h"
35 #include "plist.h"
36 #include "stream.h"
37 #include "prefix.h"
38 #include "table.h"
39 #include "qobj.h"
40 #include "zclient.h"
41 #include "vrf.h"
42 #include "spf_backoff.h"
43 #include "lib/northbound_cli.h"
44 #include "bfd.h"
45
46 #include "isisd/isis_constants.h"
47 #include "isisd/isis_common.h"
48 #include "isisd/isis_flags.h"
49 #include "isisd/isis_circuit.h"
50 #include "isisd/isis_csm.h"
51 #include "isisd/isisd.h"
52 #include "isisd/isis_dynhn.h"
53 #include "isisd/isis_adjacency.h"
54 #include "isisd/isis_pdu.h"
55 #include "isisd/isis_misc.h"
56 #include "isisd/isis_constants.h"
57 #include "isisd/isis_lsp.h"
58 #include "isisd/isis_spf.h"
59 #include "isisd/isis_route.h"
60 #include "isisd/isis_zebra.h"
61 #include "isisd/isis_events.h"
62 #include "isisd/isis_te.h"
63 #include "isisd/isis_mt.h"
64 #include "isisd/isis_sr.h"
65 #include "isisd/fabricd.h"
66 #include "isisd/isis_nb.h"
67
68 /* For debug statement. */
69 unsigned long debug_adj_pkt;
70 unsigned long debug_snp_pkt;
71 unsigned long debug_update_pkt;
72 unsigned long debug_spf_events;
73 unsigned long debug_rte_events;
74 unsigned long debug_events;
75 unsigned long debug_pkt_dump;
76 unsigned long debug_lsp_gen;
77 unsigned long debug_lsp_sched;
78 unsigned long debug_flooding;
79 unsigned long debug_bfd;
80 unsigned long debug_tx_queue;
81 unsigned long debug_sr;
82 unsigned long debug_ldp_sync;
83 unsigned long debug_lfa;
84
85 DEFINE_MGROUP(ISISD, "isisd");
86
87 DEFINE_MTYPE_STATIC(ISISD, ISIS, "ISIS process");
88 DEFINE_MTYPE_STATIC(ISISD, ISIS_NAME, "ISIS process name");
89 DEFINE_MTYPE_STATIC(ISISD, ISIS_AREA, "ISIS area");
90 DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address");
91 DEFINE_MTYPE(ISISD, ISIS_ACL_NAME, "ISIS access-list name");
92
93 DEFINE_QOBJ_TYPE(isis_area);
94
95 /* ISIS process wide configuration. */
96 static struct isis_master isis_master;
97
98 /* ISIS process wide configuration pointer to export. */
99 struct isis_master *im;
100
101 #ifndef FABRICD
102 DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
103 #endif /* ifndef FABRICD */
104
105 /*
106 * Prototypes.
107 */
108 int isis_area_get(struct vty *, const char *);
109 int area_net_title(struct vty *, const char *);
110 int area_clear_net_title(struct vty *, const char *);
111 int show_isis_interface_common(struct vty *, const char *ifname, char,
112 const char *vrf_name, bool all_vrf);
113 int show_isis_neighbor_common(struct vty *, const char *id, char,
114 const char *vrf_name, bool all_vrf);
115 int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
116 bool all_vrf);
117
118 /* Link ISIS instance to VRF. */
119 void isis_vrf_link(struct isis *isis, struct vrf *vrf)
120 {
121 isis->vrf_id = vrf->vrf_id;
122 if (vrf->info != (void *)isis)
123 vrf->info = (void *)isis;
124 }
125
126 /* Unlink ISIS instance to VRF. */
127 void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
128 {
129 if (vrf->info == (void *)isis)
130 vrf->info = NULL;
131 isis->vrf_id = VRF_UNKNOWN;
132 }
133
134 struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
135 {
136 struct isis *isis;
137 struct listnode *node;
138
139 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
140 if (isis->vrf_id == vrf_id)
141 return isis;
142
143 return NULL;
144 }
145
146 struct isis *isis_lookup_by_vrfname(const char *vrfname)
147 {
148 struct isis *isis;
149 struct listnode *node;
150
151 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
152 if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
153 return isis;
154
155 return NULL;
156 }
157
158 struct isis *isis_lookup_by_sysid(const uint8_t *sysid)
159 {
160 struct isis *isis;
161 struct listnode *node;
162
163 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
164 if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
165 return isis;
166
167 return NULL;
168 }
169
170 void isis_master_init(struct thread_master *master)
171 {
172 memset(&isis_master, 0, sizeof(struct isis_master));
173 im = &isis_master;
174 im->isis = list_new();
175 im->master = master;
176 }
177
178 struct isis *isis_new(const char *vrf_name)
179 {
180 struct vrf *vrf;
181 struct isis *isis;
182
183 isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
184
185 isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
186
187 vrf = vrf_lookup_by_name(vrf_name);
188
189 if (vrf)
190 isis_vrf_link(isis, vrf);
191 else
192 isis->vrf_id = VRF_UNKNOWN;
193
194 isis_zebra_vrf_register(isis);
195
196 if (IS_DEBUG_EVENTS)
197 zlog_debug(
198 "%s: Create new isis instance with vrf_name %s vrf_id %u",
199 __func__, isis->name, isis->vrf_id);
200
201 /*
202 * Default values
203 */
204 isis->max_area_addrs = 3;
205 isis->process_id = getpid();
206 isis->router_id = 0;
207 isis->area_list = list_new();
208 isis->uptime = time(NULL);
209 isis->snmp_notifications = 1;
210 dyn_cache_init(isis);
211
212 listnode_add(im->isis, isis);
213
214 return isis;
215 }
216
217 void isis_finish(struct isis *isis)
218 {
219 struct vrf *vrf = NULL;
220
221 listnode_delete(im->isis, isis);
222
223 isis_zebra_vrf_deregister(isis);
224
225 vrf = vrf_lookup_by_name(isis->name);
226 if (vrf)
227 isis_vrf_unlink(isis, vrf);
228 XFREE(MTYPE_ISIS_NAME, isis->name);
229
230 isis_redist_free(isis);
231 list_delete(&isis->area_list);
232 dyn_cache_finish(isis);
233 XFREE(MTYPE_ISIS, isis);
234 }
235
236 void isis_area_add_circuit(struct isis_area *area, struct isis_circuit *circuit)
237 {
238 isis_csm_state_change(ISIS_ENABLE, circuit, area);
239
240 area->ip_circuits += circuit->ip_router;
241 area->ipv6_circuits += circuit->ipv6_router;
242
243 area->lfa_protected_links[0] += circuit->lfa_protection[0];
244 area->rlfa_protected_links[0] += circuit->rlfa_protection[0];
245 area->tilfa_protected_links[0] += circuit->tilfa_protection[0];
246
247 area->lfa_protected_links[1] += circuit->lfa_protection[1];
248 area->rlfa_protected_links[1] += circuit->rlfa_protection[1];
249 area->tilfa_protected_links[1] += circuit->tilfa_protection[1];
250 }
251
252 void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit)
253 {
254 area->ip_circuits -= circuit->ip_router;
255 area->ipv6_circuits -= circuit->ipv6_router;
256
257 area->lfa_protected_links[0] -= circuit->lfa_protection[0];
258 area->rlfa_protected_links[0] -= circuit->rlfa_protection[0];
259 area->tilfa_protected_links[0] -= circuit->tilfa_protection[0];
260
261 area->lfa_protected_links[1] -= circuit->lfa_protection[1];
262 area->rlfa_protected_links[1] -= circuit->rlfa_protection[1];
263 area->tilfa_protected_links[1] -= circuit->tilfa_protection[1];
264
265 isis_csm_state_change(ISIS_DISABLE, circuit, area);
266 }
267
268 struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
269 {
270 struct isis_area *area;
271 struct isis *isis = NULL;
272 struct vrf *vrf = NULL;
273 struct interface *ifp;
274 struct isis_circuit *circuit;
275
276 area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
277
278 if (!vrf_name)
279 vrf_name = VRF_DEFAULT_NAME;
280
281 vrf = vrf_lookup_by_name(vrf_name);
282 isis = isis_lookup_by_vrfname(vrf_name);
283
284 if (isis == NULL)
285 isis = isis_new(vrf_name);
286
287 listnode_add(isis->area_list, area);
288 area->isis = isis;
289
290 /*
291 * Fabricd runs only as level-2.
292 * For IS-IS, the default is level-1-2
293 */
294 if (fabricd)
295 area->is_type = IS_LEVEL_2;
296 else
297 area->is_type = yang_get_default_enum(
298 "/frr-isisd:isis/instance/is-type");
299
300 /*
301 * intialize the databases
302 */
303 if (area->is_type & IS_LEVEL_1)
304 lsp_db_init(&area->lspdb[0]);
305 if (area->is_type & IS_LEVEL_2)
306 lsp_db_init(&area->lspdb[1]);
307
308 spftree_area_init(area);
309
310 area->circuit_list = list_new();
311 area->adjacency_list = list_new();
312 area->area_addrs = list_new();
313 if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
314 thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
315 flags_initialize(&area->flags);
316
317 isis_sr_area_init(area);
318
319 /*
320 * Default values
321 */
322 #ifndef FABRICD
323 enum isis_metric_style default_style;
324
325 area->max_lsp_lifetime[0] = yang_get_default_uint16(
326 "/frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime");
327 area->max_lsp_lifetime[1] = yang_get_default_uint16(
328 "/frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime");
329 area->lsp_refresh[0] = yang_get_default_uint16(
330 "/frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval");
331 area->lsp_refresh[1] = yang_get_default_uint16(
332 "/frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval");
333 area->lsp_gen_interval[0] = yang_get_default_uint16(
334 "/frr-isisd:isis/instance/lsp/timers/level-1/generation-interval");
335 area->lsp_gen_interval[1] = yang_get_default_uint16(
336 "/frr-isisd:isis/instance/lsp/timers/level-2/generation-interval");
337 area->min_spf_interval[0] = yang_get_default_uint16(
338 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
339 area->min_spf_interval[1] = yang_get_default_uint16(
340 "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
341 area->dynhostname = yang_get_default_bool(
342 "/frr-isisd:isis/instance/dynamic-hostname");
343 default_style =
344 yang_get_default_enum("/frr-isisd:isis/instance/metric-style");
345 area->oldmetric = default_style == ISIS_WIDE_METRIC ? 0 : 1;
346 area->newmetric = default_style == ISIS_NARROW_METRIC ? 0 : 1;
347 area->lsp_frag_threshold = 90; /* not currently configurable */
348 area->lsp_mtu =
349 yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu");
350 area->lfa_load_sharing[0] = yang_get_default_bool(
351 "/frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing");
352 area->lfa_load_sharing[1] = yang_get_default_bool(
353 "/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing");
354 area->attached_bit_send =
355 yang_get_default_bool("/frr-isisd:isis/instance/attach-send");
356 area->attached_bit_rcv_ignore = yang_get_default_bool(
357 "/frr-isisd:isis/instance/attach-receive-ignore");
358
359 #else
360 area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */
361 area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */
362 area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
363 area->lsp_refresh[1] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
364 area->lsp_gen_interval[0] = DEFAULT_MIN_LSP_GEN_INTERVAL;
365 area->lsp_gen_interval[1] = DEFAULT_MIN_LSP_GEN_INTERVAL;
366 area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
367 area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
368 area->dynhostname = 1;
369 area->oldmetric = 0;
370 area->newmetric = 1;
371 area->lsp_frag_threshold = 90;
372 area->lsp_mtu = DEFAULT_LSP_MTU;
373 area->lfa_load_sharing[0] = true;
374 area->lfa_load_sharing[1] = true;
375 area->attached_bit_send = true;
376 area->attached_bit_rcv_ignore = false;
377 #endif /* ifndef FABRICD */
378 area->lfa_priority_limit[0] = SPF_PREFIX_PRIO_LOW;
379 area->lfa_priority_limit[1] = SPF_PREFIX_PRIO_LOW;
380 isis_lfa_tiebreakers_init(area, ISIS_LEVEL1);
381 isis_lfa_tiebreakers_init(area, ISIS_LEVEL2);
382
383 area_mt_init(area);
384
385 area->area_tag = strdup(area_tag);
386
387 if (fabricd)
388 area->fabricd = fabricd_new(area);
389
390 area->lsp_refresh_arg[0].area = area;
391 area->lsp_refresh_arg[0].level = IS_LEVEL_1;
392 area->lsp_refresh_arg[1].area = area;
393 area->lsp_refresh_arg[1].level = IS_LEVEL_2;
394
395 area->bfd_signalled_down = false;
396 area->bfd_force_spf_refresh = false;
397
398 QOBJ_REG(area, isis_area);
399
400 if (vrf) {
401 FOR_ALL_INTERFACES (vrf, ifp) {
402 if (ifp->ifindex == IFINDEX_INTERNAL)
403 continue;
404
405 circuit = ifp->info;
406 if (circuit && strmatch(circuit->tag, area->area_tag))
407 isis_area_add_circuit(area, circuit);
408 }
409 }
410
411 return area;
412 }
413
414 struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
415 const char *vrf_name)
416 {
417 struct isis_area *area;
418 struct listnode *node;
419 struct isis *isis = NULL;
420
421 isis = isis_lookup_by_vrfname(vrf_name);
422 if (isis == NULL)
423 return NULL;
424
425 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
426 if (strcmp(area->area_tag, area_tag) == 0)
427 return area;
428
429 return NULL;
430 }
431
432 struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id)
433 {
434 struct isis_area *area;
435 struct listnode *node;
436 struct isis *isis;
437
438 isis = isis_lookup_by_vrfid(vrf_id);
439 if (isis == NULL)
440 return NULL;
441
442 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
443 if ((area->area_tag == NULL && area_tag == NULL)
444 || (area->area_tag && area_tag
445 && strcmp(area->area_tag, area_tag) == 0))
446 return area;
447
448 return NULL;
449 }
450
451 int isis_area_get(struct vty *vty, const char *area_tag)
452 {
453 struct isis_area *area;
454
455 area = isis_area_lookup(area_tag, VRF_DEFAULT);
456
457 if (area) {
458 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
459 return CMD_SUCCESS;
460 }
461
462 area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
463
464 if (IS_DEBUG_EVENTS)
465 zlog_debug("New IS-IS area instance %s", area->area_tag);
466
467 VTY_PUSH_CONTEXT(ROUTER_NODE, area);
468
469 return CMD_SUCCESS;
470 }
471
472 /* return the number of Level1 and level-1-2 routers or
473 * the number of Level2 and level-1-2 routers configured
474 */
475 int isis_area_count(const struct isis *isis, int levels)
476 {
477 struct isis_area *area;
478 struct listnode *node;
479 int count = 0;
480
481 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
482 if (area->is_type & levels)
483 count++;
484
485 return count;
486 }
487
488 void isis_area_destroy(struct isis_area *area)
489 {
490 struct listnode *node, *nnode;
491 struct isis_circuit *circuit;
492 struct area_addr *addr;
493
494 QOBJ_UNREG(area);
495
496 if (fabricd)
497 fabricd_finish(area->fabricd);
498
499 /* Disable MPLS if necessary before flooding LSP */
500 if (IS_MPLS_TE(area->mta))
501 area->mta->status = disable;
502
503 if (area->circuit_list) {
504 for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
505 circuit))
506 isis_area_del_circuit(area, circuit);
507
508 list_delete(&area->circuit_list);
509 }
510 list_delete(&area->adjacency_list);
511
512 lsp_db_fini(&area->lspdb[0]);
513 lsp_db_fini(&area->lspdb[1]);
514
515 /* invalidate and verify to delete all routes from zebra */
516 isis_area_invalidate_routes(area, area->is_type);
517 isis_area_verify_routes(area);
518
519 isis_sr_area_term(area);
520
521 spftree_area_del(area);
522
523 if (area->spf_timer[0])
524 isis_spf_timer_free(THREAD_ARG(area->spf_timer[0]));
525 thread_cancel(&area->spf_timer[0]);
526 if (area->spf_timer[1])
527 isis_spf_timer_free(THREAD_ARG(area->spf_timer[1]));
528 thread_cancel(&area->spf_timer[1]);
529
530 spf_backoff_free(area->spf_delay_ietf[0]);
531 spf_backoff_free(area->spf_delay_ietf[1]);
532
533 if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
534 isis_redist_area_finish(area);
535
536 for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) {
537 list_delete_node(area->area_addrs, node);
538 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
539 }
540 area->area_addrs = NULL;
541
542 for (int i = SPF_PREFIX_PRIO_CRITICAL; i <= SPF_PREFIX_PRIO_MEDIUM;
543 i++) {
544 struct spf_prefix_priority_acl *ppa;
545
546 ppa = &area->spf_prefix_priorities[i];
547 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
548 }
549 isis_lfa_tiebreakers_clear(area, ISIS_LEVEL1);
550 isis_lfa_tiebreakers_clear(area, ISIS_LEVEL2);
551
552 thread_cancel(&area->t_tick);
553 thread_cancel(&area->t_lsp_refresh[0]);
554 thread_cancel(&area->t_lsp_refresh[1]);
555 thread_cancel(&area->t_rlfa_rib_update);
556
557 thread_cancel_event(master, area);
558
559 listnode_delete(area->isis->area_list, area);
560
561 free(area->area_tag);
562
563 area_mt_finish(area);
564
565 if (listcount(area->isis->area_list) == 0) {
566 isis_finish(area->isis);
567 }
568
569 XFREE(MTYPE_ISIS_AREA, area);
570
571 }
572
573 /* This is hook function for vrf create called as part of vrf_init */
574 static int isis_vrf_new(struct vrf *vrf)
575 {
576 if (IS_DEBUG_EVENTS)
577 zlog_debug("%s: VRF Created: %s(%u)", __func__, vrf->name,
578 vrf->vrf_id);
579
580 return 0;
581 }
582
583 /* This is hook function for vrf delete call as part of vrf_init */
584 static int isis_vrf_delete(struct vrf *vrf)
585 {
586 if (IS_DEBUG_EVENTS)
587 zlog_debug("%s: VRF Deletion: %s(%u)", __func__, vrf->name,
588 vrf->vrf_id);
589
590 return 0;
591 }
592
593 static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set)
594 {
595 struct listnode *node;
596 struct isis_area *area;
597 int type;
598 int level;
599 int protocol;
600
601 char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1];
602
603 memset(do_subscribe, 0, sizeof(do_subscribe));
604
605 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
606 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
607 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
608 for (level = 0; level < ISIS_LEVELS; level++)
609 if (area->redist_settings[protocol]
610 [type][level]
611 .redist
612 == 1)
613 do_subscribe[protocol][type] =
614 1;
615
616 for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
617 for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) {
618 /* This field is actually controlling transmission of
619 * the IS-IS
620 * routes to Zebra and has nothing to do with
621 * redistribution,
622 * so skip it. */
623 if (type == PROTO_TYPE)
624 continue;
625
626 if (!do_subscribe[protocol][type])
627 continue;
628
629 afi_t afi = afi_for_redist_protocol(protocol);
630
631 if (type == DEFAULT_ROUTE) {
632 if (set)
633 vrf_bitmap_set(
634 zclient->default_information
635 [afi],
636 isis->vrf_id);
637 else
638 vrf_bitmap_unset(
639 zclient->default_information
640 [afi],
641 isis->vrf_id);
642 } else {
643 if (set)
644 vrf_bitmap_set(
645 zclient->redist[afi][type],
646 isis->vrf_id);
647 else
648 vrf_bitmap_unset(
649 zclient->redist[afi][type],
650 isis->vrf_id);
651 }
652 }
653 }
654
655 static int isis_vrf_enable(struct vrf *vrf)
656 {
657 struct isis *isis;
658 vrf_id_t old_vrf_id;
659
660 if (IS_DEBUG_EVENTS)
661 zlog_debug("%s: VRF %s id %u enabled", __func__, vrf->name,
662 vrf->vrf_id);
663
664 isis = isis_lookup_by_vrfname(vrf->name);
665 if (isis) {
666 old_vrf_id = isis->vrf_id;
667 /* We have instance configured, link to VRF and make it "up". */
668 isis_vrf_link(isis, vrf);
669 if (IS_DEBUG_EVENTS)
670 zlog_debug(
671 "%s: isis linked to vrf %s vrf_id %u (old id %u)",
672 __func__, vrf->name, isis->vrf_id, old_vrf_id);
673 if (old_vrf_id != isis->vrf_id) {
674 /* start zebra redist to us for new vrf */
675 isis_set_redist_vrf_bitmaps(isis, true);
676
677 isis_zebra_vrf_register(isis);
678 }
679 }
680
681 return 0;
682 }
683
684 static int isis_vrf_disable(struct vrf *vrf)
685 {
686 struct isis *isis;
687 vrf_id_t old_vrf_id = VRF_UNKNOWN;
688
689 if (vrf->vrf_id == VRF_DEFAULT)
690 return 0;
691
692 if (IS_DEBUG_EVENTS)
693 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
694 vrf->vrf_id);
695 isis = isis_lookup_by_vrfname(vrf->name);
696 if (isis) {
697 old_vrf_id = isis->vrf_id;
698
699 isis_zebra_vrf_deregister(isis);
700
701 isis_set_redist_vrf_bitmaps(isis, false);
702
703 /* We have instance configured, unlink
704 * from VRF and make it "down".
705 */
706 isis_vrf_unlink(isis, vrf);
707 if (IS_DEBUG_EVENTS)
708 zlog_debug("%s: isis old_vrf_id %d unlinked", __func__,
709 old_vrf_id);
710 }
711
712 return 0;
713 }
714
715 void isis_vrf_init(void)
716 {
717 vrf_init(isis_vrf_new, isis_vrf_enable, isis_vrf_disable,
718 isis_vrf_delete, isis_vrf_enable);
719
720 vrf_cmd_init(NULL, &isisd_privs);
721 }
722
723 void isis_terminate()
724 {
725 struct isis *isis;
726 struct listnode *node, *nnode;
727
728 bfd_protocol_integration_set_shutdown(true);
729
730 if (listcount(im->isis) == 0)
731 return;
732
733 for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
734 isis_finish(isis);
735 }
736
737 void isis_filter_update(struct access_list *access)
738 {
739 struct isis *isis;
740 struct isis_area *area;
741 struct listnode *node, *anode;
742
743 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
744 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
745 for (int i = SPF_PREFIX_PRIO_CRITICAL;
746 i <= SPF_PREFIX_PRIO_MEDIUM; i++) {
747 struct spf_prefix_priority_acl *ppa;
748
749 ppa = &area->spf_prefix_priorities[i];
750 ppa->list_v4 =
751 access_list_lookup(AFI_IP, ppa->name);
752 ppa->list_v6 =
753 access_list_lookup(AFI_IP6, ppa->name);
754 }
755 lsp_regenerate_schedule(area, area->is_type, 0);
756 }
757 }
758 }
759
760 void isis_prefix_list_update(struct prefix_list *plist)
761 {
762 struct isis *isis;
763 struct isis_area *area;
764 struct listnode *node, *anode;
765
766 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
767 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
768 for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS;
769 level++) {
770 const char *plist_name =
771 prefix_list_name(plist);
772
773 if (!area->rlfa_plist_name[level - 1])
774 continue;
775
776 if (!strmatch(area->rlfa_plist_name[level - 1],
777 plist_name))
778 continue;
779
780 area->rlfa_plist[level - 1] =
781 prefix_list_lookup(AFI_IP, plist_name);
782 lsp_regenerate_schedule(area, area->is_type, 0);
783 }
784 }
785 }
786 }
787
788 #ifdef FABRICD
789 static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid,
790 bool enabled)
791 {
792 struct isis_area_mt_setting *setting;
793
794 setting = area_get_mt_setting(area, mtid);
795 if (setting->enabled != enabled) {
796 setting->enabled = enabled;
797 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
798 }
799 }
800
801 static void area_set_mt_overload(struct isis_area *area, uint16_t mtid,
802 bool overload)
803 {
804 struct isis_area_mt_setting *setting;
805
806 setting = area_get_mt_setting(area, mtid);
807 if (setting->overload != overload) {
808 setting->overload = overload;
809 if (setting->enabled)
810 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2,
811 0);
812 }
813 }
814 #endif /* ifdef FABRICD */
815
816 int area_net_title(struct vty *vty, const char *net_title)
817 {
818 VTY_DECLVAR_CONTEXT(isis_area, area);
819 struct area_addr *addr;
820 struct area_addr *addrp;
821 struct listnode *node;
822
823 uint8_t buff[255];
824
825 /* We check that we are not over the maximal number of addresses */
826 if (listcount(area->area_addrs) >= area->isis->max_area_addrs) {
827 vty_out(vty,
828 "Maximum of area addresses (%d) already reached \n",
829 area->isis->max_area_addrs);
830 return CMD_ERR_NOTHING_TODO;
831 }
832
833 addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
834 addr->addr_len = dotformat2buff(buff, net_title);
835 memcpy(addr->area_addr, buff, addr->addr_len);
836 #ifdef EXTREME_DEBUG
837 zlog_debug("added area address %s for area %s (address length %d)",
838 net_title, area->area_tag, addr->addr_len);
839 #endif /* EXTREME_DEBUG */
840 if (addr->addr_len < 8 || addr->addr_len > 20) {
841 vty_out(vty,
842 "area address must be at least 8..20 octets long (%d)\n",
843 addr->addr_len);
844 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
845 return CMD_WARNING_CONFIG_FAILED;
846 }
847
848 if (addr->area_addr[addr->addr_len - 1] != 0) {
849 vty_out(vty,
850 "nsel byte (last byte) in area address must be 0\n");
851 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
852 return CMD_WARNING_CONFIG_FAILED;
853 }
854
855 if (area->isis->sysid_set == 0) {
856 /*
857 * First area address - get the SystemID for this router
858 */
859 memcpy(area->isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
860 area->isis->sysid_set = 1;
861 if (IS_DEBUG_EVENTS)
862 zlog_debug("Router has SystemID %s",
863 sysid_print(area->isis->sysid));
864 } else {
865 /*
866 * Check that the SystemID portions match
867 */
868 if (memcmp(area->isis->sysid, GETSYSID(addr),
869 ISIS_SYS_ID_LEN)) {
870 vty_out(vty,
871 "System ID must not change when defining additional area addresses\n");
872 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
873 return CMD_WARNING_CONFIG_FAILED;
874 }
875
876 /* now we see that we don't already have this address */
877 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
878 if ((addrp->addr_len + ISIS_SYS_ID_LEN + ISIS_NSEL_LEN)
879 != (addr->addr_len))
880 continue;
881 if (!memcmp(addrp->area_addr, addr->area_addr,
882 addr->addr_len)) {
883 XFREE(MTYPE_ISIS_AREA_ADDR, addr);
884 return CMD_SUCCESS; /* silent fail */
885 }
886 }
887 }
888
889 /*
890 * Forget the systemID part of the address
891 */
892 addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
893 listnode_add(area->area_addrs, addr);
894
895 /* only now we can safely generate our LSPs for this area */
896 if (listcount(area->area_addrs) > 0) {
897 if (area->is_type & IS_LEVEL_1)
898 lsp_generate(area, IS_LEVEL_1);
899 if (area->is_type & IS_LEVEL_2)
900 lsp_generate(area, IS_LEVEL_2);
901 }
902
903 return CMD_SUCCESS;
904 }
905
906 int area_clear_net_title(struct vty *vty, const char *net_title)
907 {
908 VTY_DECLVAR_CONTEXT(isis_area, area);
909 struct area_addr addr, *addrp = NULL;
910 struct listnode *node;
911 uint8_t buff[255];
912
913 addr.addr_len = dotformat2buff(buff, net_title);
914 if (addr.addr_len < 8 || addr.addr_len > 20) {
915 vty_out(vty,
916 "Unsupported area address length %d, should be 8...20 \n",
917 addr.addr_len);
918 return CMD_WARNING_CONFIG_FAILED;
919 }
920
921 memcpy(addr.area_addr, buff, (int)addr.addr_len);
922
923 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp))
924 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
925 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
926 break;
927
928 if (!addrp) {
929 vty_out(vty, "No area address %s for area %s \n", net_title,
930 area->area_tag);
931 return CMD_ERR_NO_MATCH;
932 }
933
934 listnode_delete(area->area_addrs, addrp);
935 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
936
937 /*
938 * Last area address - reset the SystemID for this router
939 */
940 if (listcount(area->area_addrs) == 0) {
941 memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
942 area->isis->sysid_set = 0;
943 if (IS_DEBUG_EVENTS)
944 zlog_debug("Router has no SystemID");
945 }
946
947 return CMD_SUCCESS;
948 }
949
950 /*
951 * 'show isis interface' command
952 */
953
954 int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
955 const char *vrf_name, bool all_vrf)
956 {
957 struct listnode *anode, *cnode, *inode;
958 struct isis_area *area;
959 struct isis_circuit *circuit;
960 struct isis *isis;
961
962 if (!im) {
963 vty_out(vty, "IS-IS Routing Process not enabled\n");
964 return CMD_SUCCESS;
965 }
966 if (vrf_name) {
967 if (all_vrf) {
968 for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
969 for (ALL_LIST_ELEMENTS_RO(isis->area_list,
970 anode, area)) {
971 vty_out(vty, "Area %s:\n",
972 area->area_tag);
973
974 if (detail == ISIS_UI_LEVEL_BRIEF)
975 vty_out(vty,
976 " Interface CircId State Type Level\n");
977
978 for (ALL_LIST_ELEMENTS_RO(
979 area->circuit_list, cnode,
980 circuit))
981 if (!ifname)
982 isis_circuit_print_vty(
983 circuit, vty,
984 detail);
985 else if (strcmp(circuit->interface->name, ifname) == 0)
986 isis_circuit_print_vty(
987 circuit, vty,
988 detail);
989 }
990 }
991 return CMD_SUCCESS;
992 }
993 isis = isis_lookup_by_vrfname(vrf_name);
994 if (isis != NULL) {
995 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
996 area)) {
997 vty_out(vty, "Area %s:\n", area->area_tag);
998
999 if (detail == ISIS_UI_LEVEL_BRIEF)
1000 vty_out(vty,
1001 " Interface CircId State Type Level\n");
1002
1003 for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
1004 cnode, circuit))
1005 if (!ifname)
1006 isis_circuit_print_vty(
1007 circuit, vty, detail);
1008 else if (
1009 strcmp(circuit->interface->name,
1010 ifname)
1011 == 0)
1012 isis_circuit_print_vty(
1013 circuit, vty, detail);
1014 }
1015 }
1016 }
1017
1018 return CMD_SUCCESS;
1019 }
1020
1021 DEFUN(show_isis_interface,
1022 show_isis_interface_cmd,
1023 "show " PROTO_NAME " [vrf <NAME|all>] interface",
1024 SHOW_STR
1025 PROTO_HELP
1026 VRF_CMD_HELP_STR
1027 "All VRFs\n"
1028 "IS-IS interface\n")
1029 {
1030 const char *vrf_name = VRF_DEFAULT_NAME;
1031 bool all_vrf = false;
1032 int idx_vrf = 0;
1033
1034 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1035 return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
1036 vrf_name, all_vrf);
1037 }
1038
1039 DEFUN(show_isis_interface_detail,
1040 show_isis_interface_detail_cmd,
1041 "show " PROTO_NAME " [vrf <NAME|all>] interface detail",
1042 SHOW_STR
1043 PROTO_HELP
1044 VRF_CMD_HELP_STR
1045 "All VRFs\n"
1046 "IS-IS interface\n"
1047 "show detailed information\n")
1048 {
1049 const char *vrf_name = VRF_DEFAULT_NAME;
1050 bool all_vrf = false;
1051 int idx_vrf = 0;
1052
1053 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1054 return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
1055 vrf_name, all_vrf);
1056 }
1057
1058 DEFUN(show_isis_interface_arg,
1059 show_isis_interface_arg_cmd,
1060 "show " PROTO_NAME " [vrf <NAME|all>] interface WORD",
1061 SHOW_STR
1062 PROTO_HELP
1063 VRF_CMD_HELP_STR
1064 "All VRFs\n"
1065 "IS-IS interface\n"
1066 "IS-IS interface name\n")
1067 {
1068 int idx_word = 0;
1069 const char *vrf_name = VRF_DEFAULT_NAME;
1070 bool all_vrf = false;
1071 int idx_vrf = 0;
1072
1073 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1074
1075 char *ifname = argv_find(argv, argc, "WORD", &idx_word)
1076 ? argv[idx_word]->arg
1077 : NULL;
1078 return show_isis_interface_common(vty, ifname, ISIS_UI_LEVEL_DETAIL,
1079 vrf_name, all_vrf);
1080 }
1081
1082 static int id_to_sysid(struct isis *isis, const char *id, uint8_t *sysid)
1083 {
1084 struct isis_dynhn *dynhn;
1085
1086 memset(sysid, 0, ISIS_SYS_ID_LEN);
1087 if (id) {
1088 if (sysid2buff(sysid, id) == 0) {
1089 dynhn = dynhn_find_by_name(isis, id);
1090 if (dynhn == NULL)
1091 return -1;
1092 memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
1093 }
1094 }
1095
1096 return 0;
1097 }
1098
1099 static void isis_neighbor_common(struct vty *vty, const char *id, char detail,
1100 struct isis *isis, uint8_t *sysid)
1101 {
1102 struct listnode *anode, *cnode, *node;
1103 struct isis_area *area;
1104 struct isis_circuit *circuit;
1105 struct list *adjdb;
1106 struct isis_adjacency *adj;
1107 int i;
1108
1109 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
1110 vty_out(vty, "Area %s:\n", area->area_tag);
1111
1112 if (detail == ISIS_UI_LEVEL_BRIEF)
1113 vty_out(vty,
1114 " System Id Interface L State Holdtime SNPA\n");
1115
1116 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
1117 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
1118 for (i = 0; i < 2; i++) {
1119 adjdb = circuit->u.bc.adjdb[i];
1120 if (adjdb && adjdb->count) {
1121 for (ALL_LIST_ELEMENTS_RO(
1122 adjdb, node, adj))
1123 if (!id
1124 || !memcmp(
1125 adj->sysid,
1126 sysid,
1127 ISIS_SYS_ID_LEN))
1128 isis_adj_print_vty(
1129 adj,
1130 vty,
1131 detail);
1132 }
1133 }
1134 } else if (circuit->circ_type == CIRCUIT_T_P2P
1135 && circuit->u.p2p.neighbor) {
1136 adj = circuit->u.p2p.neighbor;
1137 if (!id
1138 || !memcmp(adj->sysid, sysid,
1139 ISIS_SYS_ID_LEN))
1140 isis_adj_print_vty(adj, vty, detail);
1141 }
1142 }
1143 }
1144
1145 }
1146 /*
1147 * 'show isis neighbor' command
1148 */
1149
1150 int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
1151 const char *vrf_name, bool all_vrf)
1152 {
1153 struct listnode *node;
1154 uint8_t sysid[ISIS_SYS_ID_LEN];
1155 struct isis *isis;
1156
1157 if (!im) {
1158 vty_out(vty, "IS-IS Routing Process not enabled\n");
1159 return CMD_SUCCESS;
1160 }
1161
1162 if (vrf_name) {
1163 if (all_vrf) {
1164 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
1165 if (id_to_sysid(isis, id, sysid)) {
1166 vty_out(vty, "Invalid system id %s\n",
1167 id);
1168 return CMD_SUCCESS;
1169 }
1170 isis_neighbor_common(vty, id, detail, isis,
1171 sysid);
1172 }
1173 return CMD_SUCCESS;
1174 }
1175 isis = isis_lookup_by_vrfname(vrf_name);
1176 if (isis != NULL) {
1177 if (id_to_sysid(isis, id, sysid)) {
1178 vty_out(vty, "Invalid system id %s\n", id);
1179 return CMD_SUCCESS;
1180 }
1181 isis_neighbor_common(vty, id, detail, isis, sysid);
1182 }
1183 }
1184
1185 return CMD_SUCCESS;
1186 }
1187
1188 static void isis_neighbor_common_clear(struct vty *vty, const char *id,
1189 uint8_t *sysid, struct isis *isis)
1190 {
1191 struct listnode *anode, *cnode, *node, *nnode;
1192 struct isis_area *area;
1193 struct isis_circuit *circuit;
1194 struct list *adjdb;
1195 struct isis_adjacency *adj;
1196 int i;
1197
1198 for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
1199 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
1200 if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
1201 for (i = 0; i < 2; i++) {
1202 adjdb = circuit->u.bc.adjdb[i];
1203 if (adjdb && adjdb->count) {
1204 for (ALL_LIST_ELEMENTS(
1205 adjdb, node, nnode,
1206 adj))
1207 if (!id
1208 || !memcmp(
1209 adj->sysid,
1210 sysid,
1211 ISIS_SYS_ID_LEN))
1212 isis_adj_state_change(
1213 &adj,
1214 ISIS_ADJ_DOWN,
1215 "clear user request");
1216 }
1217 }
1218 } else if (circuit->circ_type == CIRCUIT_T_P2P
1219 && circuit->u.p2p.neighbor) {
1220 adj = circuit->u.p2p.neighbor;
1221 if (!id
1222 || !memcmp(adj->sysid, sysid,
1223 ISIS_SYS_ID_LEN))
1224 isis_adj_state_change(
1225 &adj, ISIS_ADJ_DOWN,
1226 "clear user request");
1227 }
1228 }
1229 }
1230 }
1231 /*
1232 * 'clear isis neighbor' command
1233 */
1234 int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
1235 bool all_vrf)
1236 {
1237 struct listnode *node;
1238 uint8_t sysid[ISIS_SYS_ID_LEN];
1239 struct isis *isis;
1240
1241 if (!im) {
1242 vty_out(vty, "IS-IS Routing Process not enabled\n");
1243 return CMD_SUCCESS;
1244 }
1245
1246 if (vrf_name) {
1247 if (all_vrf) {
1248 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
1249 if (id_to_sysid(isis, id, sysid)) {
1250 vty_out(vty, "Invalid system id %s\n",
1251 id);
1252 return CMD_SUCCESS;
1253 }
1254 isis_neighbor_common_clear(vty, id, sysid,
1255 isis);
1256 }
1257 return CMD_SUCCESS;
1258 }
1259 isis = isis_lookup_by_vrfname(vrf_name);
1260 if (isis != NULL) {
1261 if (id_to_sysid(isis, id, sysid)) {
1262 vty_out(vty, "Invalid system id %s\n", id);
1263 return CMD_SUCCESS;
1264 }
1265 isis_neighbor_common_clear(vty, id, sysid, isis);
1266 }
1267 }
1268
1269 return CMD_SUCCESS;
1270 }
1271
1272 DEFUN(show_isis_neighbor,
1273 show_isis_neighbor_cmd,
1274 "show " PROTO_NAME " [vrf <NAME|all>] neighbor",
1275 SHOW_STR
1276 PROTO_HELP
1277 VRF_CMD_HELP_STR
1278 "All vrfs\n"
1279 "IS-IS neighbor adjacencies\n")
1280 {
1281 const char *vrf_name = VRF_DEFAULT_NAME;
1282 bool all_vrf = false;
1283 int idx_vrf = 0;
1284
1285 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1286 return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
1287 vrf_name, all_vrf);
1288 }
1289
1290 DEFUN(show_isis_neighbor_detail,
1291 show_isis_neighbor_detail_cmd,
1292 "show " PROTO_NAME " [vrf <NAME|all>] neighbor detail",
1293 SHOW_STR
1294 PROTO_HELP
1295 VRF_CMD_HELP_STR
1296 "all vrfs\n"
1297 "IS-IS neighbor adjacencies\n"
1298 "show detailed information\n")
1299 {
1300 const char *vrf_name = VRF_DEFAULT_NAME;
1301 bool all_vrf = false;
1302 int idx_vrf = 0;
1303
1304 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1305
1306 return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
1307 vrf_name, all_vrf);
1308 }
1309
1310 DEFUN(show_isis_neighbor_arg,
1311 show_isis_neighbor_arg_cmd,
1312 "show " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
1313 SHOW_STR
1314 PROTO_HELP
1315 VRF_CMD_HELP_STR
1316 "All vrfs\n"
1317 "IS-IS neighbor adjacencies\n"
1318 "System id\n")
1319 {
1320 int idx_word = 0;
1321 const char *vrf_name = VRF_DEFAULT_NAME;
1322 bool all_vrf = false;
1323 int idx_vrf = 0;
1324
1325 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1326 char *id = argv_find(argv, argc, "WORD", &idx_word)
1327 ? argv[idx_word]->arg
1328 : NULL;
1329
1330 return show_isis_neighbor_common(vty, id, ISIS_UI_LEVEL_DETAIL,
1331 vrf_name, all_vrf);
1332 }
1333
1334 DEFUN(clear_isis_neighbor,
1335 clear_isis_neighbor_cmd,
1336 "clear " PROTO_NAME " [vrf <NAME|all>] neighbor",
1337 CLEAR_STR
1338 PROTO_HELP
1339 VRF_CMD_HELP_STR
1340 "All vrfs\n"
1341 "IS-IS neighbor adjacencies\n")
1342 {
1343 const char *vrf_name = VRF_DEFAULT_NAME;
1344 bool all_vrf = false;
1345 int idx_vrf = 0;
1346
1347 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1348 return clear_isis_neighbor_common(vty, NULL, vrf_name, all_vrf);
1349 }
1350
1351 DEFUN(clear_isis_neighbor_arg,
1352 clear_isis_neighbor_arg_cmd,
1353 "clear " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
1354 CLEAR_STR
1355 PROTO_HELP
1356 VRF_CMD_HELP_STR
1357 "All vrfs\n"
1358 "IS-IS neighbor adjacencies\n"
1359 "System id\n")
1360 {
1361 int idx_word = 0;
1362 const char *vrf_name = VRF_DEFAULT_NAME;
1363 bool all_vrf = false;
1364 int idx_vrf = 0;
1365
1366 char *id = argv_find(argv, argc, "WORD", &idx_word)
1367 ? argv[idx_word]->arg
1368 : NULL;
1369 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1370 return clear_isis_neighbor_common(vty, id, vrf_name, all_vrf);
1371 }
1372
1373 /*
1374 * 'isis debug', 'show debugging'
1375 */
1376 void print_debug(struct vty *vty, int flags, int onoff)
1377 {
1378 const char *onoffs = onoff ? "on" : "off";
1379
1380 if (flags & DEBUG_ADJ_PACKETS)
1381 vty_out(vty,
1382 "IS-IS Adjacency related packets debugging is %s\n",
1383 onoffs);
1384 if (flags & DEBUG_TX_QUEUE)
1385 vty_out(vty, "IS-IS TX queue debugging is %s\n",
1386 onoffs);
1387 if (flags & DEBUG_SNP_PACKETS)
1388 vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n",
1389 onoffs);
1390 if (flags & DEBUG_SPF_EVENTS)
1391 vty_out(vty, "IS-IS SPF events debugging is %s\n", onoffs);
1392 if (flags & DEBUG_SR)
1393 vty_out(vty, "IS-IS Segment Routing events debugging is %s\n",
1394 onoffs);
1395 if (flags & DEBUG_LFA)
1396 vty_out(vty, "IS-IS LFA events debugging is %s\n", onoffs);
1397 if (flags & DEBUG_UPDATE_PACKETS)
1398 vty_out(vty, "IS-IS Update related packet debugging is %s\n",
1399 onoffs);
1400 if (flags & DEBUG_RTE_EVENTS)
1401 vty_out(vty, "IS-IS Route related debuggin is %s\n", onoffs);
1402 if (flags & DEBUG_EVENTS)
1403 vty_out(vty, "IS-IS Event debugging is %s\n", onoffs);
1404 if (flags & DEBUG_PACKET_DUMP)
1405 vty_out(vty, "IS-IS Packet dump debugging is %s\n", onoffs);
1406 if (flags & DEBUG_LSP_GEN)
1407 vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs);
1408 if (flags & DEBUG_LSP_SCHED)
1409 vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs);
1410 if (flags & DEBUG_FLOODING)
1411 vty_out(vty, "IS-IS Flooding debugging is %s\n", onoffs);
1412 if (flags & DEBUG_BFD)
1413 vty_out(vty, "IS-IS BFD debugging is %s\n", onoffs);
1414 if (flags & DEBUG_LDP_SYNC)
1415 vty_out(vty, "IS-IS ldp-sync debugging is %s\n", onoffs);
1416 }
1417
1418 DEFUN_NOSH (show_debugging,
1419 show_debugging_isis_cmd,
1420 "show debugging [" PROTO_NAME "]",
1421 SHOW_STR
1422 "State of each debugging option\n"
1423 PROTO_HELP)
1424 {
1425 vty_out(vty, PROTO_NAME " debugging status:\n");
1426
1427 if (IS_DEBUG_ADJ_PACKETS)
1428 print_debug(vty, DEBUG_ADJ_PACKETS, 1);
1429 if (IS_DEBUG_TX_QUEUE)
1430 print_debug(vty, DEBUG_TX_QUEUE, 1);
1431 if (IS_DEBUG_SNP_PACKETS)
1432 print_debug(vty, DEBUG_SNP_PACKETS, 1);
1433 if (IS_DEBUG_SPF_EVENTS)
1434 print_debug(vty, DEBUG_SPF_EVENTS, 1);
1435 if (IS_DEBUG_SR)
1436 print_debug(vty, DEBUG_SR, 1);
1437 if (IS_DEBUG_UPDATE_PACKETS)
1438 print_debug(vty, DEBUG_UPDATE_PACKETS, 1);
1439 if (IS_DEBUG_RTE_EVENTS)
1440 print_debug(vty, DEBUG_RTE_EVENTS, 1);
1441 if (IS_DEBUG_EVENTS)
1442 print_debug(vty, DEBUG_EVENTS, 1);
1443 if (IS_DEBUG_PACKET_DUMP)
1444 print_debug(vty, DEBUG_PACKET_DUMP, 1);
1445 if (IS_DEBUG_LSP_GEN)
1446 print_debug(vty, DEBUG_LSP_GEN, 1);
1447 if (IS_DEBUG_LSP_SCHED)
1448 print_debug(vty, DEBUG_LSP_SCHED, 1);
1449 if (IS_DEBUG_FLOODING)
1450 print_debug(vty, DEBUG_FLOODING, 1);
1451 if (IS_DEBUG_BFD)
1452 print_debug(vty, DEBUG_BFD, 1);
1453 if (IS_DEBUG_LDP_SYNC)
1454 print_debug(vty, DEBUG_LDP_SYNC, 1);
1455 if (IS_DEBUG_LFA)
1456 print_debug(vty, DEBUG_LFA, 1);
1457
1458 return CMD_SUCCESS;
1459 }
1460
1461 static int config_write_debug(struct vty *vty);
1462 /* Debug node. */
1463 static struct cmd_node debug_node = {
1464 .name = "debug",
1465 .node = DEBUG_NODE,
1466 .prompt = "",
1467 .config_write = config_write_debug,
1468 };
1469
1470 static int config_write_debug(struct vty *vty)
1471 {
1472 int write = 0;
1473
1474 if (IS_DEBUG_ADJ_PACKETS) {
1475 vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
1476 write++;
1477 }
1478 if (IS_DEBUG_TX_QUEUE) {
1479 vty_out(vty, "debug " PROTO_NAME " tx-queue\n");
1480 write++;
1481 }
1482 if (IS_DEBUG_SNP_PACKETS) {
1483 vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
1484 write++;
1485 }
1486 if (IS_DEBUG_SPF_EVENTS) {
1487 vty_out(vty, "debug " PROTO_NAME " spf-events\n");
1488 write++;
1489 }
1490 if (IS_DEBUG_SR) {
1491 vty_out(vty, "debug " PROTO_NAME " sr-events\n");
1492 write++;
1493 }
1494 if (IS_DEBUG_LFA) {
1495 vty_out(vty, "debug " PROTO_NAME " lfa\n");
1496 write++;
1497 }
1498 if (IS_DEBUG_UPDATE_PACKETS) {
1499 vty_out(vty, "debug " PROTO_NAME " update-packets\n");
1500 write++;
1501 }
1502 if (IS_DEBUG_RTE_EVENTS) {
1503 vty_out(vty, "debug " PROTO_NAME " route-events\n");
1504 write++;
1505 }
1506 if (IS_DEBUG_EVENTS) {
1507 vty_out(vty, "debug " PROTO_NAME " events\n");
1508 write++;
1509 }
1510 if (IS_DEBUG_PACKET_DUMP) {
1511 vty_out(vty, "debug " PROTO_NAME " packet-dump\n");
1512 write++;
1513 }
1514 if (IS_DEBUG_LSP_GEN) {
1515 vty_out(vty, "debug " PROTO_NAME " lsp-gen\n");
1516 write++;
1517 }
1518 if (IS_DEBUG_LSP_SCHED) {
1519 vty_out(vty, "debug " PROTO_NAME " lsp-sched\n");
1520 write++;
1521 }
1522 if (IS_DEBUG_FLOODING) {
1523 vty_out(vty, "debug " PROTO_NAME " flooding\n");
1524 write++;
1525 }
1526 if (IS_DEBUG_BFD) {
1527 vty_out(vty, "debug " PROTO_NAME " bfd\n");
1528 write++;
1529 }
1530 if (IS_DEBUG_LDP_SYNC) {
1531 vty_out(vty, "debug " PROTO_NAME " ldp-sync\n");
1532 write++;
1533 }
1534 write += spf_backoff_write_config(vty);
1535
1536 return write;
1537 }
1538
1539 DEFUN (debug_isis_adj,
1540 debug_isis_adj_cmd,
1541 "debug " PROTO_NAME " adj-packets",
1542 DEBUG_STR
1543 PROTO_HELP
1544 "IS-IS Adjacency related packets\n")
1545 {
1546 debug_adj_pkt |= DEBUG_ADJ_PACKETS;
1547 print_debug(vty, DEBUG_ADJ_PACKETS, 1);
1548
1549 return CMD_SUCCESS;
1550 }
1551
1552 DEFUN (no_debug_isis_adj,
1553 no_debug_isis_adj_cmd,
1554 "no debug " PROTO_NAME " adj-packets",
1555 NO_STR
1556 UNDEBUG_STR
1557 PROTO_HELP
1558 "IS-IS Adjacency related packets\n")
1559 {
1560 debug_adj_pkt &= ~DEBUG_ADJ_PACKETS;
1561 print_debug(vty, DEBUG_ADJ_PACKETS, 0);
1562
1563 return CMD_SUCCESS;
1564 }
1565
1566 DEFUN (debug_isis_tx_queue,
1567 debug_isis_tx_queue_cmd,
1568 "debug " PROTO_NAME " tx-queue",
1569 DEBUG_STR
1570 PROTO_HELP
1571 "IS-IS TX queues\n")
1572 {
1573 debug_tx_queue |= DEBUG_TX_QUEUE;
1574 print_debug(vty, DEBUG_TX_QUEUE, 1);
1575
1576 return CMD_SUCCESS;
1577 }
1578
1579 DEFUN (no_debug_isis_tx_queue,
1580 no_debug_isis_tx_queue_cmd,
1581 "no debug " PROTO_NAME " tx-queue",
1582 NO_STR
1583 UNDEBUG_STR
1584 PROTO_HELP
1585 "IS-IS TX queues\n")
1586 {
1587 debug_tx_queue &= ~DEBUG_TX_QUEUE;
1588 print_debug(vty, DEBUG_TX_QUEUE, 0);
1589
1590 return CMD_SUCCESS;
1591 }
1592
1593 DEFUN (debug_isis_flooding,
1594 debug_isis_flooding_cmd,
1595 "debug " PROTO_NAME " flooding",
1596 DEBUG_STR
1597 PROTO_HELP
1598 "Flooding algorithm\n")
1599 {
1600 debug_flooding |= DEBUG_FLOODING;
1601 print_debug(vty, DEBUG_FLOODING, 1);
1602
1603 return CMD_SUCCESS;
1604 }
1605
1606 DEFUN (no_debug_isis_flooding,
1607 no_debug_isis_flooding_cmd,
1608 "no debug " PROTO_NAME " flooding",
1609 NO_STR
1610 UNDEBUG_STR
1611 PROTO_HELP
1612 "Flooding algorithm\n")
1613 {
1614 debug_flooding &= ~DEBUG_FLOODING;
1615 print_debug(vty, DEBUG_FLOODING, 0);
1616
1617 return CMD_SUCCESS;
1618 }
1619
1620 DEFUN (debug_isis_snp,
1621 debug_isis_snp_cmd,
1622 "debug " PROTO_NAME " snp-packets",
1623 DEBUG_STR
1624 PROTO_HELP
1625 "IS-IS CSNP/PSNP packets\n")
1626 {
1627 debug_snp_pkt |= DEBUG_SNP_PACKETS;
1628 print_debug(vty, DEBUG_SNP_PACKETS, 1);
1629
1630 return CMD_SUCCESS;
1631 }
1632
1633 DEFUN (no_debug_isis_snp,
1634 no_debug_isis_snp_cmd,
1635 "no debug " PROTO_NAME " snp-packets",
1636 NO_STR
1637 UNDEBUG_STR
1638 PROTO_HELP
1639 "IS-IS CSNP/PSNP packets\n")
1640 {
1641 debug_snp_pkt &= ~DEBUG_SNP_PACKETS;
1642 print_debug(vty, DEBUG_SNP_PACKETS, 0);
1643
1644 return CMD_SUCCESS;
1645 }
1646
1647 DEFUN (debug_isis_upd,
1648 debug_isis_upd_cmd,
1649 "debug " PROTO_NAME " update-packets",
1650 DEBUG_STR
1651 PROTO_HELP
1652 "IS-IS Update related packets\n")
1653 {
1654 debug_update_pkt |= DEBUG_UPDATE_PACKETS;
1655 print_debug(vty, DEBUG_UPDATE_PACKETS, 1);
1656
1657 return CMD_SUCCESS;
1658 }
1659
1660 DEFUN (no_debug_isis_upd,
1661 no_debug_isis_upd_cmd,
1662 "no debug " PROTO_NAME " update-packets",
1663 NO_STR
1664 UNDEBUG_STR
1665 PROTO_HELP
1666 "IS-IS Update related packets\n")
1667 {
1668 debug_update_pkt &= ~DEBUG_UPDATE_PACKETS;
1669 print_debug(vty, DEBUG_UPDATE_PACKETS, 0);
1670
1671 return CMD_SUCCESS;
1672 }
1673
1674 DEFUN (debug_isis_spfevents,
1675 debug_isis_spfevents_cmd,
1676 "debug " PROTO_NAME " spf-events",
1677 DEBUG_STR
1678 PROTO_HELP
1679 "IS-IS Shortest Path First Events\n")
1680 {
1681 debug_spf_events |= DEBUG_SPF_EVENTS;
1682 print_debug(vty, DEBUG_SPF_EVENTS, 1);
1683
1684 return CMD_SUCCESS;
1685 }
1686
1687 DEFUN (no_debug_isis_spfevents,
1688 no_debug_isis_spfevents_cmd,
1689 "no debug " PROTO_NAME " spf-events",
1690 NO_STR
1691 UNDEBUG_STR
1692 PROTO_HELP
1693 "IS-IS Shortest Path First Events\n")
1694 {
1695 debug_spf_events &= ~DEBUG_SPF_EVENTS;
1696 print_debug(vty, DEBUG_SPF_EVENTS, 0);
1697
1698 return CMD_SUCCESS;
1699 }
1700
1701 DEFUN (debug_isis_srevents,
1702 debug_isis_srevents_cmd,
1703 "debug " PROTO_NAME " sr-events",
1704 DEBUG_STR
1705 PROTO_HELP
1706 "IS-IS Segment Routing Events\n")
1707 {
1708 debug_sr |= DEBUG_SR;
1709 print_debug(vty, DEBUG_SR, 1);
1710
1711 return CMD_SUCCESS;
1712 }
1713
1714 DEFUN (no_debug_isis_srevents,
1715 no_debug_isis_srevents_cmd,
1716 "no debug " PROTO_NAME " sr-events",
1717 NO_STR
1718 UNDEBUG_STR
1719 PROTO_HELP
1720 "IS-IS Segment Routing Events\n")
1721 {
1722 debug_sr &= ~DEBUG_SR;
1723 print_debug(vty, DEBUG_SR, 0);
1724
1725 return CMD_SUCCESS;
1726 }
1727
1728 DEFUN (debug_isis_lfa,
1729 debug_isis_lfa_cmd,
1730 "debug " PROTO_NAME " lfa",
1731 DEBUG_STR
1732 PROTO_HELP
1733 "IS-IS LFA Events\n")
1734 {
1735 debug_lfa |= DEBUG_LFA;
1736 print_debug(vty, DEBUG_LFA, 1);
1737
1738 return CMD_SUCCESS;
1739 }
1740
1741 DEFUN (no_debug_isis_lfa,
1742 no_debug_isis_lfa_cmd,
1743 "no debug " PROTO_NAME " lfa",
1744 NO_STR
1745 UNDEBUG_STR
1746 PROTO_HELP
1747 "IS-IS LFA Events\n")
1748 {
1749 debug_lfa &= ~DEBUG_LFA;
1750 print_debug(vty, DEBUG_LFA, 0);
1751
1752 return CMD_SUCCESS;
1753 }
1754
1755 DEFUN (debug_isis_rtevents,
1756 debug_isis_rtevents_cmd,
1757 "debug " PROTO_NAME " route-events",
1758 DEBUG_STR
1759 PROTO_HELP
1760 "IS-IS Route related events\n")
1761 {
1762 debug_rte_events |= DEBUG_RTE_EVENTS;
1763 print_debug(vty, DEBUG_RTE_EVENTS, 1);
1764
1765 return CMD_SUCCESS;
1766 }
1767
1768 DEFUN (no_debug_isis_rtevents,
1769 no_debug_isis_rtevents_cmd,
1770 "no debug " PROTO_NAME " route-events",
1771 NO_STR
1772 UNDEBUG_STR
1773 PROTO_HELP
1774 "IS-IS Route related events\n")
1775 {
1776 debug_rte_events &= ~DEBUG_RTE_EVENTS;
1777 print_debug(vty, DEBUG_RTE_EVENTS, 0);
1778
1779 return CMD_SUCCESS;
1780 }
1781
1782 DEFUN (debug_isis_events,
1783 debug_isis_events_cmd,
1784 "debug " PROTO_NAME " events",
1785 DEBUG_STR
1786 PROTO_HELP
1787 "IS-IS Events\n")
1788 {
1789 debug_events |= DEBUG_EVENTS;
1790 print_debug(vty, DEBUG_EVENTS, 1);
1791
1792 return CMD_SUCCESS;
1793 }
1794
1795 DEFUN (no_debug_isis_events,
1796 no_debug_isis_events_cmd,
1797 "no debug " PROTO_NAME " events",
1798 NO_STR
1799 UNDEBUG_STR
1800 PROTO_HELP
1801 "IS-IS Events\n")
1802 {
1803 debug_events &= ~DEBUG_EVENTS;
1804 print_debug(vty, DEBUG_EVENTS, 0);
1805
1806 return CMD_SUCCESS;
1807 }
1808
1809 DEFUN (debug_isis_packet_dump,
1810 debug_isis_packet_dump_cmd,
1811 "debug " PROTO_NAME " packet-dump",
1812 DEBUG_STR
1813 PROTO_HELP
1814 "IS-IS packet dump\n")
1815 {
1816 debug_pkt_dump |= DEBUG_PACKET_DUMP;
1817 print_debug(vty, DEBUG_PACKET_DUMP, 1);
1818
1819 return CMD_SUCCESS;
1820 }
1821
1822 DEFUN (no_debug_isis_packet_dump,
1823 no_debug_isis_packet_dump_cmd,
1824 "no debug " PROTO_NAME " packet-dump",
1825 NO_STR
1826 UNDEBUG_STR
1827 PROTO_HELP
1828 "IS-IS packet dump\n")
1829 {
1830 debug_pkt_dump &= ~DEBUG_PACKET_DUMP;
1831 print_debug(vty, DEBUG_PACKET_DUMP, 0);
1832
1833 return CMD_SUCCESS;
1834 }
1835
1836 DEFUN (debug_isis_lsp_gen,
1837 debug_isis_lsp_gen_cmd,
1838 "debug " PROTO_NAME " lsp-gen",
1839 DEBUG_STR
1840 PROTO_HELP
1841 "IS-IS generation of own LSPs\n")
1842 {
1843 debug_lsp_gen |= DEBUG_LSP_GEN;
1844 print_debug(vty, DEBUG_LSP_GEN, 1);
1845
1846 return CMD_SUCCESS;
1847 }
1848
1849 DEFUN (no_debug_isis_lsp_gen,
1850 no_debug_isis_lsp_gen_cmd,
1851 "no debug " PROTO_NAME " lsp-gen",
1852 NO_STR
1853 UNDEBUG_STR
1854 PROTO_HELP
1855 "IS-IS generation of own LSPs\n")
1856 {
1857 debug_lsp_gen &= ~DEBUG_LSP_GEN;
1858 print_debug(vty, DEBUG_LSP_GEN, 0);
1859
1860 return CMD_SUCCESS;
1861 }
1862
1863 DEFUN (debug_isis_lsp_sched,
1864 debug_isis_lsp_sched_cmd,
1865 "debug " PROTO_NAME " lsp-sched",
1866 DEBUG_STR
1867 PROTO_HELP
1868 "IS-IS scheduling of LSP generation\n")
1869 {
1870 debug_lsp_sched |= DEBUG_LSP_SCHED;
1871 print_debug(vty, DEBUG_LSP_SCHED, 1);
1872
1873 return CMD_SUCCESS;
1874 }
1875
1876 DEFUN (no_debug_isis_lsp_sched,
1877 no_debug_isis_lsp_sched_cmd,
1878 "no debug " PROTO_NAME " lsp-sched",
1879 NO_STR
1880 UNDEBUG_STR
1881 PROTO_HELP
1882 "IS-IS scheduling of LSP generation\n")
1883 {
1884 debug_lsp_sched &= ~DEBUG_LSP_SCHED;
1885 print_debug(vty, DEBUG_LSP_SCHED, 0);
1886
1887 return CMD_SUCCESS;
1888 }
1889
1890 DEFUN (debug_isis_bfd,
1891 debug_isis_bfd_cmd,
1892 "debug " PROTO_NAME " bfd",
1893 DEBUG_STR
1894 PROTO_HELP
1895 PROTO_NAME " interaction with BFD\n")
1896 {
1897 debug_bfd |= DEBUG_BFD;
1898 print_debug(vty, DEBUG_BFD, 1);
1899
1900 return CMD_SUCCESS;
1901 }
1902
1903 DEFUN (no_debug_isis_bfd,
1904 no_debug_isis_bfd_cmd,
1905 "no debug " PROTO_NAME " bfd",
1906 NO_STR
1907 UNDEBUG_STR
1908 PROTO_HELP
1909 PROTO_NAME " interaction with BFD\n")
1910 {
1911 debug_bfd &= ~DEBUG_BFD;
1912 print_debug(vty, DEBUG_BFD, 0);
1913
1914 return CMD_SUCCESS;
1915 }
1916
1917 DEFUN(debug_isis_ldp_sync, debug_isis_ldp_sync_cmd,
1918 "debug " PROTO_NAME " ldp-sync",
1919 DEBUG_STR PROTO_HELP PROTO_NAME " interaction with LDP-Sync\n")
1920 {
1921 debug_ldp_sync |= DEBUG_LDP_SYNC;
1922 print_debug(vty, DEBUG_LDP_SYNC, 1);
1923
1924 return CMD_SUCCESS;
1925 }
1926
1927 DEFUN(no_debug_isis_ldp_sync, no_debug_isis_ldp_sync_cmd,
1928 "no debug " PROTO_NAME " ldp-sync",
1929 NO_STR UNDEBUG_STR PROTO_HELP PROTO_NAME " interaction with LDP-Sync\n")
1930 {
1931 debug_ldp_sync &= ~DEBUG_LDP_SYNC;
1932 print_debug(vty, DEBUG_LDP_SYNC, 0);
1933
1934 return CMD_SUCCESS;
1935 }
1936
1937 DEFUN (show_hostname,
1938 show_hostname_cmd,
1939 "show " PROTO_NAME " [vrf <NAME|all>] hostname",
1940 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
1941 "All VRFs\n"
1942 "IS-IS Dynamic hostname mapping\n")
1943 {
1944 struct listnode *node;
1945 const char *vrf_name = VRF_DEFAULT_NAME;
1946 bool all_vrf = false;
1947 int idx_vrf = 0;
1948 struct isis *isis;
1949
1950 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1951 if (vrf_name) {
1952 if (all_vrf) {
1953 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
1954 dynhn_print_all(vty, isis);
1955
1956 return CMD_SUCCESS;
1957 }
1958 isis = isis_lookup_by_vrfname(vrf_name);
1959 if (isis != NULL)
1960 dynhn_print_all(vty, isis);
1961 }
1962
1963 return CMD_SUCCESS;
1964 }
1965
1966 static void isis_spf_ietf_common(struct vty *vty, struct isis *isis)
1967 {
1968 struct listnode *node;
1969 struct isis_area *area;
1970 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
1971
1972 vty_out(vty, "vrf : %s\n", isis->name);
1973 vty_out(vty, "Area %s:\n",
1974 area->area_tag ? area->area_tag : "null");
1975
1976 for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
1977 if ((area->is_type & level) == 0)
1978 continue;
1979
1980 vty_out(vty, " Level-%d:\n", level);
1981 vty_out(vty, " SPF delay status: ");
1982 if (area->spf_timer[level - 1]) {
1983 struct timeval remain = thread_timer_remain(
1984 area->spf_timer[level - 1]);
1985 vty_out(vty, "Pending, due in %lld msec\n",
1986 (long long)remain.tv_sec * 1000
1987 + remain.tv_usec / 1000);
1988 } else {
1989 vty_out(vty, "Not scheduled\n");
1990 }
1991
1992 if (area->spf_delay_ietf[level - 1]) {
1993 vty_out(vty,
1994 " Using draft-ietf-rtgwg-backoff-algo-04\n");
1995 spf_backoff_show(
1996 area->spf_delay_ietf[level - 1], vty,
1997 " ");
1998 } else {
1999 vty_out(vty, " Using legacy backoff algo\n");
2000 }
2001 }
2002 }
2003 }
2004
2005 DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
2006 "show " PROTO_NAME " [vrf <NAME|all>] spf-delay-ietf",
2007 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2008 "All VRFs\n"
2009 "SPF delay IETF information\n")
2010 {
2011 struct listnode *node;
2012 struct isis *isis;
2013 int idx_vrf = 0;
2014 const char *vrf_name = VRF_DEFAULT_NAME;
2015 bool all_vrf = false;
2016
2017 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
2018
2019 if (!im) {
2020 vty_out(vty, "ISIS is not running\n");
2021 return CMD_SUCCESS;
2022 }
2023
2024 if (vrf_name) {
2025 if (all_vrf) {
2026 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2027 isis_spf_ietf_common(vty, isis);
2028
2029 return CMD_SUCCESS;
2030 }
2031 isis = isis_lookup_by_vrfname(vrf_name);
2032 if (isis != NULL)
2033 isis_spf_ietf_common(vty, isis);
2034 }
2035
2036 return CMD_SUCCESS;
2037 }
2038
2039 static void common_isis_summary(struct vty *vty, struct isis *isis)
2040 {
2041 struct listnode *node, *node2;
2042 struct isis_area *area;
2043 int level;
2044
2045 vty_out(vty, "vrf : %s\n", isis->name);
2046 vty_out(vty, "Process Id : %ld\n", isis->process_id);
2047 if (isis->sysid_set)
2048 vty_out(vty, "System Id : %s\n",
2049 sysid_print(isis->sysid));
2050
2051 vty_out(vty, "Up time : ");
2052 vty_out_timestr(vty, isis->uptime);
2053 vty_out(vty, "\n");
2054
2055 if (isis->area_list)
2056 vty_out(vty, "Number of areas : %d\n", isis->area_list->count);
2057
2058 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2059 vty_out(vty, "Area %s:\n",
2060 area->area_tag ? area->area_tag : "null");
2061
2062 if (fabricd) {
2063 uint8_t tier = fabricd_tier(area);
2064 if (tier == ISIS_TIER_UNDEFINED)
2065 vty_out(vty, " Tier: undefined\n");
2066 else
2067 vty_out(vty, " Tier: %hhu\n", tier);
2068 }
2069
2070 if (listcount(area->area_addrs) > 0) {
2071 struct area_addr *area_addr;
2072 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
2073 area_addr)) {
2074 vty_out(vty, " Net: %s\n",
2075 isonet_print(area_addr->area_addr,
2076 area_addr->addr_len
2077 + ISIS_SYS_ID_LEN
2078 + 1));
2079 }
2080 }
2081
2082 vty_out(vty, " TX counters per PDU type:\n");
2083 pdu_counter_print(vty, " ", area->pdu_tx_counters);
2084 vty_out(vty, " LSP RXMT: %" PRIu64 "\n",
2085 area->lsp_rxmt_count);
2086 vty_out(vty, " RX counters per PDU type:\n");
2087 pdu_counter_print(vty, " ", area->pdu_rx_counters);
2088
2089 for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
2090 if ((area->is_type & level) == 0)
2091 continue;
2092
2093 vty_out(vty, " Level-%d:\n", level);
2094
2095 vty_out(vty, " LSP0 regenerated: %" PRIu64 "\n",
2096 area->lsp_gen_count[level - 1]);
2097
2098 vty_out(vty, " LSPs purged: %" PRIu64 "\n",
2099 area->lsp_purge_count[level - 1]);
2100
2101 if (area->spf_timer[level - 1])
2102 vty_out(vty, " SPF: (pending)\n");
2103 else
2104 vty_out(vty, " SPF:\n");
2105
2106 vty_out(vty, " minimum interval : %d",
2107 area->min_spf_interval[level - 1]);
2108 if (area->spf_delay_ietf[level - 1])
2109 vty_out(vty,
2110 " (not used, IETF SPF delay activated)");
2111 vty_out(vty, "\n");
2112
2113 if (area->ip_circuits) {
2114 vty_out(vty, " IPv4 route computation:\n");
2115 isis_spf_print(
2116 area->spftree[SPFTREE_IPV4][level - 1],
2117 vty);
2118 }
2119
2120 if (area->ipv6_circuits) {
2121 vty_out(vty, " IPv6 route computation:\n");
2122 isis_spf_print(
2123 area->spftree[SPFTREE_IPV6][level - 1],
2124 vty);
2125 }
2126
2127 if (area->ipv6_circuits
2128 && isis_area_ipv6_dstsrc_enabled(area)) {
2129 vty_out(vty,
2130 " IPv6 dst-src route computation:\n");
2131 isis_spf_print(area->spftree[SPFTREE_DSTSRC]
2132 [level - 1],
2133 vty);
2134 }
2135 }
2136 }
2137 }
2138
2139 DEFUN(show_isis_summary, show_isis_summary_cmd,
2140 "show " PROTO_NAME " [vrf <NAME|all>] summary",
2141 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2142 "All VRFs\n"
2143 "summary\n")
2144 {
2145 struct listnode *node;
2146 int idx_vrf = 0;
2147 struct isis *isis;
2148 const char *vrf_name = VRF_DEFAULT_NAME;
2149 bool all_vrf = false;
2150
2151 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
2152 if (!im) {
2153 vty_out(vty, PROTO_NAME " is not running\n");
2154 return CMD_SUCCESS;
2155 }
2156 if (vrf_name) {
2157 if (all_vrf) {
2158 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2159 common_isis_summary(vty, isis);
2160
2161 return CMD_SUCCESS;
2162 }
2163 isis = isis_lookup_by_vrfname(vrf_name);
2164 if (isis != NULL)
2165 common_isis_summary(vty, isis);
2166 }
2167
2168 vty_out(vty, "\n");
2169
2170 return CMD_SUCCESS;
2171 }
2172
2173 struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
2174 struct isis *isis)
2175 {
2176 char sysid[255] = {0};
2177 uint8_t number[3] = {0};
2178 const char *pos;
2179 uint8_t lspid[ISIS_SYS_ID_LEN + 2] = {0};
2180 struct isis_dynhn *dynhn;
2181 struct isis_lsp *lsp = NULL;
2182
2183 if (!sysid_str)
2184 return NULL;
2185
2186 /*
2187 * extract fragment and pseudo id from the string sysid_str
2188 * in the forms:
2189 * (a) <systemid/hostname>.<pseudo-id>-<framenent> or
2190 * (b) <systemid/hostname>.<pseudo-id> or
2191 * (c) <systemid/hostname> or
2192 * Where systemid is in the form:
2193 * xxxx.xxxx.xxxx
2194 */
2195 strlcpy(sysid, sysid_str, sizeof(sysid));
2196
2197 if (strlen(sysid_str) > 3) {
2198 pos = sysid_str + strlen(sysid_str) - 3;
2199 if (strncmp(pos, "-", 1) == 0) {
2200 memcpy(number, ++pos, 2);
2201 lspid[ISIS_SYS_ID_LEN + 1] =
2202 (uint8_t)strtol((char *)number, NULL, 16);
2203 pos -= 4;
2204 if (strncmp(pos, ".", 1) != 0)
2205 return NULL;
2206 }
2207 if (strncmp(pos, ".", 1) == 0) {
2208 memcpy(number, ++pos, 2);
2209 lspid[ISIS_SYS_ID_LEN] =
2210 (uint8_t)strtol((char *)number, NULL, 16);
2211 sysid[pos - sysid_str - 1] = '\0';
2212 }
2213 }
2214
2215 /*
2216 * Try to find the lsp-id if the sysid_str
2217 * is in the form
2218 * hostname.<pseudo-id>-<fragment>
2219 */
2220 if (sysid2buff(lspid, sysid)) {
2221 lsp = lsp_search(head, lspid);
2222 } else if ((dynhn = dynhn_find_by_name(isis, sysid))) {
2223 memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN);
2224 lsp = lsp_search(head, lspid);
2225 } else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) {
2226 memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
2227 lsp = lsp_search(head, lspid);
2228 }
2229
2230 return lsp;
2231 }
2232
2233 void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
2234 int level, struct lspdb_head *lspdb,
2235 const char *sysid_str, int ui_level)
2236 {
2237 struct isis_lsp *lsp;
2238 int lsp_count;
2239
2240 if (lspdb_count(lspdb) > 0) {
2241 lsp = lsp_for_sysid(lspdb, sysid_str, area->isis);
2242
2243 if (lsp != NULL || sysid_str == NULL) {
2244 vty_out(vty, "IS-IS Level-%d link-state database:\n",
2245 level + 1);
2246
2247 /* print the title in all cases */
2248 vty_out(vty,
2249 "LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
2250 }
2251
2252 if (lsp) {
2253 if (ui_level == ISIS_UI_LEVEL_DETAIL)
2254 lsp_print_detail(lsp, vty, area->dynhostname,
2255 area->isis);
2256 else
2257 lsp_print(lsp, vty, area->dynhostname,
2258 area->isis);
2259 } else if (sysid_str == NULL) {
2260 lsp_count =
2261 lsp_print_all(vty, lspdb, ui_level,
2262 area->dynhostname, area->isis);
2263
2264 vty_out(vty, " %u LSPs\n\n", lsp_count);
2265 }
2266 }
2267 }
2268
2269 static void show_isis_database_common(struct vty *vty, const char *sysid_str,
2270 int ui_level, struct isis *isis)
2271 {
2272 struct listnode *node;
2273 struct isis_area *area;
2274 int level;
2275
2276 if (isis->area_list->count == 0)
2277 return;
2278
2279 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2280 vty_out(vty, "Area %s:\n",
2281 area->area_tag ? area->area_tag : "null");
2282
2283 for (level = 0; level < ISIS_LEVELS; level++)
2284 show_isis_database_lspdb(vty, area, level,
2285 &area->lspdb[level], sysid_str,
2286 ui_level);
2287 }
2288 }
2289 /*
2290 * This function supports following display options:
2291 * [ show isis database [detail] ]
2292 * [ show isis database <sysid> [detail] ]
2293 * [ show isis database <hostname> [detail] ]
2294 * [ show isis database <sysid>.<pseudo-id> [detail] ]
2295 * [ show isis database <hostname>.<pseudo-id> [detail] ]
2296 * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
2297 * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
2298 * [ show isis database detail <sysid> ]
2299 * [ show isis database detail <hostname> ]
2300 * [ show isis database detail <sysid>.<pseudo-id> ]
2301 * [ show isis database detail <hostname>.<pseudo-id> ]
2302 * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
2303 * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
2304 */
2305 static int show_isis_database(struct vty *vty, const char *sysid_str,
2306 int ui_level, const char *vrf_name, bool all_vrf)
2307 {
2308 struct listnode *node;
2309 struct isis *isis;
2310
2311 if (vrf_name) {
2312 if (all_vrf) {
2313 for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
2314 show_isis_database_common(vty, sysid_str,
2315 ui_level, isis);
2316
2317 return CMD_SUCCESS;
2318 }
2319 isis = isis_lookup_by_vrfname(vrf_name);
2320 if (isis)
2321 show_isis_database_common(vty, sysid_str, ui_level,
2322 isis);
2323 }
2324
2325 return CMD_SUCCESS;
2326 }
2327
2328 DEFUN(show_database, show_database_cmd,
2329 "show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD]",
2330 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
2331 "All VRFs\n"
2332 "Link state database\n"
2333 "Detailed information\n"
2334 "LSP ID\n")
2335 {
2336 int idx = 0;
2337 int idx_vrf = 0;
2338 const char *vrf_name = VRF_DEFAULT_NAME;
2339 bool all_vrf = false;
2340 int uilevel = argv_find(argv, argc, "detail", &idx)
2341 ? ISIS_UI_LEVEL_DETAIL
2342 : ISIS_UI_LEVEL_BRIEF;
2343 char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
2344 ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
2345 return show_isis_database(vty, id, uilevel, vrf_name, all_vrf);
2346 }
2347
2348 #ifdef FABRICD
2349 /*
2350 * 'router openfabric' command
2351 */
2352 DEFUN_NOSH (router_openfabric,
2353 router_openfabric_cmd,
2354 "router openfabric WORD",
2355 ROUTER_STR
2356 PROTO_HELP
2357 "ISO Routing area tag\n")
2358 {
2359 int idx_word = 2;
2360 return isis_area_get(vty, argv[idx_word]->arg);
2361 }
2362
2363 /*
2364 *'no router openfabric' command
2365 */
2366 DEFUN (no_router_openfabric,
2367 no_router_openfabric_cmd,
2368 "no router openfabric WORD",
2369 NO_STR
2370 ROUTER_STR
2371 PROTO_HELP
2372 "ISO Routing area tag\n")
2373 {
2374 struct isis_area *area;
2375 const char *area_tag;
2376 int idx_word = 3;
2377
2378 area_tag = argv[idx_word]->arg;
2379 area = isis_area_lookup(area_tag, VRF_DEFAULT);
2380 if (area == NULL) {
2381 zlog_warn("%s: could not find area with area-tag %s",
2382 __func__, area_tag);
2383 return CMD_ERR_NO_MATCH;
2384 }
2385
2386 isis_area_destroy(area);
2387 return CMD_SUCCESS;
2388 }
2389 #endif /* ifdef FABRICD */
2390 #ifdef FABRICD
2391 /*
2392 * 'net' command
2393 */
2394 DEFUN (net,
2395 net_cmd,
2396 "net WORD",
2397 "A Network Entity Title for this process (OSI only)\n"
2398 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2399 {
2400 int idx_word = 1;
2401 return area_net_title(vty, argv[idx_word]->arg);
2402 }
2403
2404 /*
2405 * 'no net' command
2406 */
2407 DEFUN (no_net,
2408 no_net_cmd,
2409 "no net WORD",
2410 NO_STR
2411 "A Network Entity Title for this process (OSI only)\n"
2412 "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
2413 {
2414 int idx_word = 2;
2415 return area_clear_net_title(vty, argv[idx_word]->arg);
2416 }
2417 #endif /* ifdef FABRICD */
2418 #ifdef FABRICD
2419 DEFUN (isis_topology,
2420 isis_topology_cmd,
2421 "topology " ISIS_MT_NAMES " [overload]",
2422 "Configure IS-IS topologies\n"
2423 ISIS_MT_DESCRIPTIONS
2424 "Set overload bit for topology\n")
2425 {
2426 VTY_DECLVAR_CONTEXT(isis_area, area);
2427
2428 const char *arg = argv[1]->arg;
2429 uint16_t mtid = isis_str2mtid(arg);
2430
2431 if (area->oldmetric) {
2432 vty_out(vty,
2433 "Multi topology IS-IS can only be used with wide metrics\n");
2434 return CMD_WARNING_CONFIG_FAILED;
2435 }
2436
2437 if (mtid == (uint16_t)-1) {
2438 vty_out(vty, "Don't know topology '%s'\n", arg);
2439 return CMD_WARNING_CONFIG_FAILED;
2440 }
2441 if (mtid == ISIS_MT_IPV4_UNICAST) {
2442 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
2443 return CMD_WARNING_CONFIG_FAILED;
2444 }
2445
2446 area_set_mt_enabled(area, mtid, true);
2447 area_set_mt_overload(area, mtid, (argc == 3));
2448 return CMD_SUCCESS;
2449 }
2450
2451 DEFUN (no_isis_topology,
2452 no_isis_topology_cmd,
2453 "no topology " ISIS_MT_NAMES " [overload]",
2454 NO_STR
2455 "Configure IS-IS topologies\n"
2456 ISIS_MT_DESCRIPTIONS
2457 "Set overload bit for topology\n")
2458 {
2459 VTY_DECLVAR_CONTEXT(isis_area, area);
2460
2461 const char *arg = argv[2]->arg;
2462 uint16_t mtid = isis_str2mtid(arg);
2463
2464 if (area->oldmetric) {
2465 vty_out(vty,
2466 "Multi topology IS-IS can only be used with wide metrics\n");
2467 return CMD_WARNING_CONFIG_FAILED;
2468 }
2469
2470 if (mtid == (uint16_t)-1) {
2471 vty_out(vty, "Don't know topology '%s'\n", arg);
2472 return CMD_WARNING_CONFIG_FAILED;
2473 }
2474 if (mtid == ISIS_MT_IPV4_UNICAST) {
2475 vty_out(vty, "Cannot configure IPv4 unicast topology\n");
2476 return CMD_WARNING_CONFIG_FAILED;
2477 }
2478
2479 area_set_mt_enabled(area, mtid, false);
2480 area_set_mt_overload(area, mtid, false);
2481 return CMD_SUCCESS;
2482 }
2483 #endif /* ifdef FABRICD */
2484
2485 void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
2486 {
2487 area->lsp_mtu = lsp_mtu;
2488 lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1);
2489 }
2490
2491 static int isis_area_passwd_set(struct isis_area *area, int level,
2492 uint8_t passwd_type, const char *passwd,
2493 uint8_t snp_auth)
2494 {
2495 struct isis_passwd *dest;
2496 struct isis_passwd modified;
2497 int len;
2498
2499 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
2500 dest = (level == IS_LEVEL_1) ? &area->area_passwd
2501 : &area->domain_passwd;
2502 memset(&modified, 0, sizeof(modified));
2503
2504 if (passwd_type != ISIS_PASSWD_TYPE_UNUSED) {
2505 if (!passwd)
2506 return -1;
2507
2508 len = strlen(passwd);
2509 if (len > 254)
2510 return -1;
2511
2512 modified.len = len;
2513 strlcpy((char *)modified.passwd, passwd,
2514 sizeof(modified.passwd));
2515 modified.type = passwd_type;
2516 modified.snp_auth = snp_auth;
2517 }
2518
2519 if (memcmp(&modified, dest, sizeof(modified))) {
2520 memcpy(dest, &modified, sizeof(modified));
2521 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2522 }
2523
2524 return 0;
2525 }
2526
2527 int isis_area_passwd_unset(struct isis_area *area, int level)
2528 {
2529 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_UNUSED, NULL,
2530 0);
2531 }
2532
2533 int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
2534 const char *passwd, uint8_t snp_auth)
2535 {
2536 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_CLEARTXT,
2537 passwd, snp_auth);
2538 }
2539
2540 int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
2541 const char *passwd, uint8_t snp_auth)
2542 {
2543 return isis_area_passwd_set(area, level, ISIS_PASSWD_TYPE_HMAC_MD5,
2544 passwd, snp_auth);
2545 }
2546
2547 void isis_area_invalidate_routes(struct isis_area *area, int levels)
2548 {
2549 for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
2550 if (!(level & levels))
2551 continue;
2552 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
2553 isis_spf_invalidate_routes(
2554 area->spftree[tree][level - 1]);
2555 }
2556 }
2557 }
2558
2559 void isis_area_verify_routes(struct isis_area *area)
2560 {
2561 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++)
2562 isis_spf_verify_routes(area, area->spftree[tree]);
2563 }
2564
2565 static void area_resign_level(struct isis_area *area, int level)
2566 {
2567 isis_area_invalidate_routes(area, level);
2568 isis_area_verify_routes(area);
2569
2570 lsp_db_fini(&area->lspdb[level - 1]);
2571
2572 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
2573 if (area->spftree[tree][level - 1]) {
2574 isis_spftree_del(area->spftree[tree][level - 1]);
2575 area->spftree[tree][level - 1] = NULL;
2576 }
2577 }
2578
2579 if (area->spf_timer[level - 1])
2580 isis_spf_timer_free(THREAD_ARG(area->spf_timer[level - 1]));
2581
2582 thread_cancel(&area->spf_timer[level - 1]);
2583
2584 sched_debug(
2585 "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
2586 area->area_tag, level);
2587 thread_cancel(&area->t_lsp_refresh[level - 1]);
2588 area->lsp_regenerate_pending[level - 1] = 0;
2589 }
2590
2591 void isis_area_is_type_set(struct isis_area *area, int is_type)
2592 {
2593 struct listnode *node;
2594 struct isis_circuit *circuit;
2595
2596 if (IS_DEBUG_EVENTS)
2597 zlog_debug("ISIS-Evt (%s) system type change %s -> %s",
2598 area->area_tag, circuit_t2string(area->is_type),
2599 circuit_t2string(is_type));
2600
2601 if (area->is_type == is_type)
2602 return; /* No change */
2603
2604 switch (area->is_type) {
2605 case IS_LEVEL_1:
2606 if (is_type == IS_LEVEL_2)
2607 area_resign_level(area, IS_LEVEL_1);
2608
2609 lsp_db_init(&area->lspdb[1]);
2610 break;
2611
2612 case IS_LEVEL_1_AND_2:
2613 if (is_type == IS_LEVEL_1)
2614 area_resign_level(area, IS_LEVEL_2);
2615 else
2616 area_resign_level(area, IS_LEVEL_1);
2617 break;
2618
2619 case IS_LEVEL_2:
2620 if (is_type == IS_LEVEL_1)
2621 area_resign_level(area, IS_LEVEL_2);
2622
2623 lsp_db_init(&area->lspdb[0]);
2624 break;
2625
2626 default:
2627 break;
2628 }
2629
2630 area->is_type = is_type;
2631
2632 /* override circuit's is_type */
2633 if (area->is_type != IS_LEVEL_1_AND_2) {
2634 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
2635 isis_circuit_is_type_set(circuit, is_type);
2636 }
2637
2638 spftree_area_init(area);
2639
2640 if (listcount(area->area_addrs) > 0) {
2641 if (is_type & IS_LEVEL_1)
2642 lsp_generate(area, IS_LEVEL_1);
2643 if (is_type & IS_LEVEL_2)
2644 lsp_generate(area, IS_LEVEL_2);
2645 }
2646 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2647
2648 return;
2649 }
2650
2651 void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
2652 bool new_metric)
2653 {
2654 area->oldmetric = old_metric;
2655 area->newmetric = new_metric;
2656 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2657 }
2658
2659 void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
2660 {
2661 char new_overload_bit = overload_bit ? LSPBIT_OL : 0;
2662
2663 if (new_overload_bit != area->overload_bit) {
2664 area->overload_bit = new_overload_bit;
2665
2666 if (new_overload_bit)
2667 area->overload_counter++;
2668
2669 #ifndef FABRICD
2670 hook_call(isis_hook_db_overload, area);
2671 #endif /* ifndef FABRICD */
2672
2673 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2674 }
2675 #ifndef FABRICD
2676 isis_notif_db_overload(area, overload_bit);
2677 #endif /* ifndef FABRICD */
2678 }
2679
2680 void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit)
2681 {
2682
2683 if (attached_bit != area->attached_bit_send) {
2684 area->attached_bit_send = attached_bit;
2685 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2686 }
2687 }
2688
2689 void isis_area_attached_bit_receive_set(struct isis_area *area,
2690 bool attached_bit)
2691 {
2692
2693 if (attached_bit != area->attached_bit_rcv_ignore) {
2694 area->attached_bit_rcv_ignore = attached_bit;
2695 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
2696 }
2697 }
2698
2699 void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname)
2700 {
2701 if (area->dynhostname != dynhostname) {
2702 area->dynhostname = dynhostname;
2703 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
2704 }
2705 }
2706
2707 void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
2708 uint16_t max_lsp_lifetime)
2709 {
2710 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
2711
2712 if (area->max_lsp_lifetime[level - 1] == max_lsp_lifetime)
2713 return;
2714
2715 area->max_lsp_lifetime[level - 1] = max_lsp_lifetime;
2716 lsp_regenerate_schedule(area, level, 1);
2717 }
2718
2719 void isis_area_lsp_refresh_set(struct isis_area *area, int level,
2720 uint16_t lsp_refresh)
2721 {
2722 assert((level == IS_LEVEL_1) || (level == IS_LEVEL_2));
2723
2724 if (area->lsp_refresh[level - 1] == lsp_refresh)
2725 return;
2726
2727 area->lsp_refresh[level - 1] = lsp_refresh;
2728 lsp_regenerate_schedule(area, level, 1);
2729 }
2730
2731 #ifdef FABRICD
2732 DEFUN (log_adj_changes,
2733 log_adj_changes_cmd,
2734 "log-adjacency-changes",
2735 "Log changes in adjacency state\n")
2736 {
2737 VTY_DECLVAR_CONTEXT(isis_area, area);
2738
2739 area->log_adj_changes = 1;
2740
2741 return CMD_SUCCESS;
2742 }
2743
2744 DEFUN (no_log_adj_changes,
2745 no_log_adj_changes_cmd,
2746 "no log-adjacency-changes",
2747 NO_STR
2748 "Stop logging changes in adjacency state\n")
2749 {
2750 VTY_DECLVAR_CONTEXT(isis_area, area);
2751
2752 area->log_adj_changes = 0;
2753
2754 return CMD_SUCCESS;
2755 }
2756 #endif /* ifdef FABRICD */
2757 #ifdef FABRICD
2758 /* IS-IS configuration write function */
2759 static int isis_config_write(struct vty *vty)
2760 {
2761 int write = 0;
2762 struct isis_area *area;
2763 struct listnode *node, *node2, *inode;
2764 struct isis *isis;
2765
2766 if (!im) {
2767 vty_out(vty, "IS-IS Routing Process not enabled\n");
2768 return CMD_SUCCESS;
2769 }
2770
2771 for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
2772 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
2773 /* ISIS - Area name */
2774 vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
2775 write++;
2776 /* ISIS - Net */
2777 if (listcount(area->area_addrs) > 0) {
2778 struct area_addr *area_addr;
2779 for (ALL_LIST_ELEMENTS_RO(area->area_addrs,
2780 node2, area_addr)) {
2781 vty_out(vty, " net %s\n",
2782 isonet_print(
2783 area_addr->area_addr,
2784 area_addr->addr_len
2785 + ISIS_SYS_ID_LEN
2786 + 1));
2787 write++;
2788 }
2789 }
2790 /* ISIS - Dynamic hostname - Defaults to true so only
2791 * display if
2792 * false. */
2793 if (!area->dynhostname) {
2794 vty_out(vty, " no hostname dynamic\n");
2795 write++;
2796 }
2797 /* ISIS - Metric-Style - when true displays wide */
2798 if (!fabricd) {
2799 if (area->newmetric) {
2800 if (!area->oldmetric)
2801 vty_out(vty, " metric-style wide\n");
2802 else
2803 vty_out(vty,
2804 " metric-style transition\n");
2805 write++;
2806 } else {
2807 vty_out(vty, " metric-style narrow\n");
2808 write++;
2809 }
2810 }
2811 /* ISIS - overload-bit */
2812 if (area->overload_bit) {
2813 vty_out(vty, " set-overload-bit\n");
2814 write++;
2815 }
2816 /* ISIS - Area is-type (level-1-2 is default) */
2817 if (!fabricd) {
2818 if (area->is_type == IS_LEVEL_1) {
2819 vty_out(vty, " is-type level-1\n");
2820 write++;
2821 } else if (area->is_type == IS_LEVEL_2) {
2822 vty_out(vty, " is-type level-2-only\n");
2823 write++;
2824 }
2825 }
2826 write += isis_redist_config_write(vty, area, AF_INET);
2827 write += isis_redist_config_write(vty, area, AF_INET6);
2828 /* ISIS - Lsp generation interval */
2829 if (area->lsp_gen_interval[0]
2830 == area->lsp_gen_interval[1]) {
2831 if (area->lsp_gen_interval[0]
2832 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
2833 vty_out(vty, " lsp-gen-interval %d\n",
2834 area->lsp_gen_interval[0]);
2835 write++;
2836 }
2837 } else {
2838 if (area->lsp_gen_interval[0]
2839 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
2840 vty_out(vty,
2841 " lsp-gen-interval level-1 %d\n",
2842 area->lsp_gen_interval[0]);
2843 write++;
2844 }
2845 if (area->lsp_gen_interval[1]
2846 != DEFAULT_MIN_LSP_GEN_INTERVAL) {
2847 vty_out(vty,
2848 " lsp-gen-interval level-2 %d\n",
2849 area->lsp_gen_interval[1]);
2850 write++;
2851 }
2852 }
2853 /* ISIS - LSP lifetime */
2854 if (area->max_lsp_lifetime[0]
2855 == area->max_lsp_lifetime[1]) {
2856 if (area->max_lsp_lifetime[0]
2857 != DEFAULT_LSP_LIFETIME) {
2858 vty_out(vty, " max-lsp-lifetime %u\n",
2859 area->max_lsp_lifetime[0]);
2860 write++;
2861 }
2862 } else {
2863 if (area->max_lsp_lifetime[0]
2864 != DEFAULT_LSP_LIFETIME) {
2865 vty_out(vty,
2866 " max-lsp-lifetime level-1 %u\n",
2867 area->max_lsp_lifetime[0]);
2868 write++;
2869 }
2870 if (area->max_lsp_lifetime[1]
2871 != DEFAULT_LSP_LIFETIME) {
2872 vty_out(vty,
2873 " max-lsp-lifetime level-2 %u\n",
2874 area->max_lsp_lifetime[1]);
2875 write++;
2876 }
2877 }
2878 /* ISIS - LSP refresh interval */
2879 if (area->lsp_refresh[0] == area->lsp_refresh[1]) {
2880 if (area->lsp_refresh[0]
2881 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
2882 vty_out(vty,
2883 " lsp-refresh-interval %u\n",
2884 area->lsp_refresh[0]);
2885 write++;
2886 }
2887 } else {
2888 if (area->lsp_refresh[0]
2889 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
2890 vty_out(vty,
2891 " lsp-refresh-interval level-1 %u\n",
2892 area->lsp_refresh[0]);
2893 write++;
2894 }
2895 if (area->lsp_refresh[1]
2896 != DEFAULT_MAX_LSP_GEN_INTERVAL) {
2897 vty_out(vty,
2898 " lsp-refresh-interval level-2 %u\n",
2899 area->lsp_refresh[1]);
2900 write++;
2901 }
2902 }
2903 if (area->lsp_mtu != DEFAULT_LSP_MTU) {
2904 vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu);
2905 write++;
2906 }
2907 if (area->purge_originator) {
2908 vty_out(vty, " purge-originator\n");
2909 write++;
2910 }
2911
2912 /* Minimum SPF interval. */
2913 if (area->min_spf_interval[0]
2914 == area->min_spf_interval[1]) {
2915 if (area->min_spf_interval[0]
2916 != MINIMUM_SPF_INTERVAL) {
2917 vty_out(vty, " spf-interval %d\n",
2918 area->min_spf_interval[0]);
2919 write++;
2920 }
2921 } else {
2922 if (area->min_spf_interval[0]
2923 != MINIMUM_SPF_INTERVAL) {
2924 vty_out(vty,
2925 " spf-interval level-1 %d\n",
2926 area->min_spf_interval[0]);
2927 write++;
2928 }
2929 if (area->min_spf_interval[1]
2930 != MINIMUM_SPF_INTERVAL) {
2931 vty_out(vty,
2932 " spf-interval level-2 %d\n",
2933 area->min_spf_interval[1]);
2934 write++;
2935 }
2936 }
2937
2938 /* IETF SPF interval */
2939 if (area->spf_delay_ietf[0]) {
2940 vty_out(vty,
2941 " spf-delay-ietf init-delay %ld short-delay %ld long-delay %ld holddown %ld time-to-learn %ld\n",
2942 spf_backoff_init_delay(
2943 area->spf_delay_ietf[0]),
2944 spf_backoff_short_delay(
2945 area->spf_delay_ietf[0]),
2946 spf_backoff_long_delay(
2947 area->spf_delay_ietf[0]),
2948 spf_backoff_holddown(
2949 area->spf_delay_ietf[0]),
2950 spf_backoff_timetolearn(
2951 area->spf_delay_ietf[0]));
2952 write++;
2953 }
2954
2955 /* Authentication passwords. */
2956 if (area->area_passwd.type
2957 == ISIS_PASSWD_TYPE_HMAC_MD5) {
2958 vty_out(vty, " area-password md5 %s",
2959 area->area_passwd.passwd);
2960 if (CHECK_FLAG(area->area_passwd.snp_auth,
2961 SNP_AUTH_SEND)) {
2962 vty_out(vty, " authenticate snp ");
2963 if (CHECK_FLAG(
2964 area->area_passwd.snp_auth,
2965 SNP_AUTH_RECV))
2966 vty_out(vty, "validate");
2967 else
2968 vty_out(vty, "send-only");
2969 }
2970 vty_out(vty, "\n");
2971 write++;
2972 } else if (area->area_passwd.type
2973 == ISIS_PASSWD_TYPE_CLEARTXT) {
2974 vty_out(vty, " area-password clear %s",
2975 area->area_passwd.passwd);
2976 if (CHECK_FLAG(area->area_passwd.snp_auth,
2977 SNP_AUTH_SEND)) {
2978 vty_out(vty, " authenticate snp ");
2979 if (CHECK_FLAG(
2980 area->area_passwd.snp_auth,
2981 SNP_AUTH_RECV))
2982 vty_out(vty, "validate");
2983 else
2984 vty_out(vty, "send-only");
2985 }
2986 vty_out(vty, "\n");
2987 write++;
2988 }
2989 if (area->domain_passwd.type
2990 == ISIS_PASSWD_TYPE_HMAC_MD5) {
2991 vty_out(vty, " domain-password md5 %s",
2992 area->domain_passwd.passwd);
2993 if (CHECK_FLAG(area->domain_passwd.snp_auth,
2994 SNP_AUTH_SEND)) {
2995 vty_out(vty, " authenticate snp ");
2996 if (CHECK_FLAG(area->domain_passwd
2997 .snp_auth,
2998 SNP_AUTH_RECV))
2999 vty_out(vty, "validate");
3000 else
3001 vty_out(vty, "send-only");
3002 }
3003 vty_out(vty, "\n");
3004 write++;
3005 } else if (area->domain_passwd.type
3006 == ISIS_PASSWD_TYPE_CLEARTXT) {
3007 vty_out(vty, " domain-password clear %s",
3008 area->domain_passwd.passwd);
3009 if (CHECK_FLAG(area->domain_passwd.snp_auth,
3010 SNP_AUTH_SEND)) {
3011 vty_out(vty, " authenticate snp ");
3012 if (CHECK_FLAG(area->domain_passwd
3013 .snp_auth,
3014 SNP_AUTH_RECV))
3015 vty_out(vty, "validate");
3016 else
3017 vty_out(vty, "send-only");
3018 }
3019 vty_out(vty, "\n");
3020 write++;
3021 }
3022
3023 if (area->log_adj_changes) {
3024 vty_out(vty, " log-adjacency-changes\n");
3025 write++;
3026 }
3027
3028 write += area_write_mt_settings(area, vty);
3029 write += fabricd_write_settings(area, vty);
3030 }
3031 }
3032
3033 return write;
3034 }
3035
3036 struct cmd_node router_node = {
3037 .name = "openfabric",
3038 .node = OPENFABRIC_NODE,
3039 .parent_node = CONFIG_NODE,
3040 .prompt = "%s(config-router)# ",
3041 .config_write = isis_config_write,
3042 };
3043 #else
3044 /* IS-IS configuration write function */
3045 static int isis_config_write(struct vty *vty)
3046 {
3047 int write = 0;
3048 struct lyd_node *dnode;
3049
3050 dnode = yang_dnode_get(running_config->dnode, "/frr-isisd:isis");
3051 if (dnode) {
3052 nb_cli_show_dnode_cmds(vty, dnode, false);
3053 write++;
3054 }
3055
3056 return write;
3057 }
3058
3059 struct cmd_node router_node = {
3060 .name = "isis",
3061 .node = ISIS_NODE,
3062 .parent_node = CONFIG_NODE,
3063 .prompt = "%s(config-router)# ",
3064 .config_write = isis_config_write,
3065 };
3066 #endif /* ifdef FABRICD */
3067
3068 void isis_init(void)
3069 {
3070 /* Install IS-IS top node */
3071 install_node(&router_node);
3072
3073 install_element(VIEW_NODE, &show_isis_summary_cmd);
3074
3075 install_element(VIEW_NODE, &show_isis_spf_ietf_cmd);
3076
3077 install_element(VIEW_NODE, &show_isis_interface_cmd);
3078 install_element(VIEW_NODE, &show_isis_interface_detail_cmd);
3079 install_element(VIEW_NODE, &show_isis_interface_arg_cmd);
3080
3081 install_element(VIEW_NODE, &show_isis_neighbor_cmd);
3082 install_element(VIEW_NODE, &show_isis_neighbor_detail_cmd);
3083 install_element(VIEW_NODE, &show_isis_neighbor_arg_cmd);
3084 install_element(ENABLE_NODE, &clear_isis_neighbor_cmd);
3085 install_element(ENABLE_NODE, &clear_isis_neighbor_arg_cmd);
3086
3087 install_element(VIEW_NODE, &show_hostname_cmd);
3088 install_element(VIEW_NODE, &show_database_cmd);
3089
3090 install_element(ENABLE_NODE, &show_debugging_isis_cmd);
3091
3092 install_node(&debug_node);
3093
3094 install_element(ENABLE_NODE, &debug_isis_adj_cmd);
3095 install_element(ENABLE_NODE, &no_debug_isis_adj_cmd);
3096 install_element(ENABLE_NODE, &debug_isis_tx_queue_cmd);
3097 install_element(ENABLE_NODE, &no_debug_isis_tx_queue_cmd);
3098 install_element(ENABLE_NODE, &debug_isis_flooding_cmd);
3099 install_element(ENABLE_NODE, &no_debug_isis_flooding_cmd);
3100 install_element(ENABLE_NODE, &debug_isis_snp_cmd);
3101 install_element(ENABLE_NODE, &no_debug_isis_snp_cmd);
3102 install_element(ENABLE_NODE, &debug_isis_upd_cmd);
3103 install_element(ENABLE_NODE, &no_debug_isis_upd_cmd);
3104 install_element(ENABLE_NODE, &debug_isis_spfevents_cmd);
3105 install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd);
3106 install_element(ENABLE_NODE, &debug_isis_srevents_cmd);
3107 install_element(ENABLE_NODE, &no_debug_isis_srevents_cmd);
3108 install_element(ENABLE_NODE, &debug_isis_lfa_cmd);
3109 install_element(ENABLE_NODE, &no_debug_isis_lfa_cmd);
3110 install_element(ENABLE_NODE, &debug_isis_rtevents_cmd);
3111 install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd);
3112 install_element(ENABLE_NODE, &debug_isis_events_cmd);
3113 install_element(ENABLE_NODE, &no_debug_isis_events_cmd);
3114 install_element(ENABLE_NODE, &debug_isis_packet_dump_cmd);
3115 install_element(ENABLE_NODE, &no_debug_isis_packet_dump_cmd);
3116 install_element(ENABLE_NODE, &debug_isis_lsp_gen_cmd);
3117 install_element(ENABLE_NODE, &no_debug_isis_lsp_gen_cmd);
3118 install_element(ENABLE_NODE, &debug_isis_lsp_sched_cmd);
3119 install_element(ENABLE_NODE, &no_debug_isis_lsp_sched_cmd);
3120 install_element(ENABLE_NODE, &debug_isis_bfd_cmd);
3121 install_element(ENABLE_NODE, &no_debug_isis_bfd_cmd);
3122 install_element(ENABLE_NODE, &debug_isis_ldp_sync_cmd);
3123 install_element(ENABLE_NODE, &no_debug_isis_ldp_sync_cmd);
3124
3125 install_element(CONFIG_NODE, &debug_isis_adj_cmd);
3126 install_element(CONFIG_NODE, &no_debug_isis_adj_cmd);
3127 install_element(CONFIG_NODE, &debug_isis_tx_queue_cmd);
3128 install_element(CONFIG_NODE, &no_debug_isis_tx_queue_cmd);
3129 install_element(CONFIG_NODE, &debug_isis_flooding_cmd);
3130 install_element(CONFIG_NODE, &no_debug_isis_flooding_cmd);
3131 install_element(CONFIG_NODE, &debug_isis_snp_cmd);
3132 install_element(CONFIG_NODE, &no_debug_isis_snp_cmd);
3133 install_element(CONFIG_NODE, &debug_isis_upd_cmd);
3134 install_element(CONFIG_NODE, &no_debug_isis_upd_cmd);
3135 install_element(CONFIG_NODE, &debug_isis_spfevents_cmd);
3136 install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd);
3137 install_element(CONFIG_NODE, &debug_isis_srevents_cmd);
3138 install_element(CONFIG_NODE, &no_debug_isis_srevents_cmd);
3139 install_element(CONFIG_NODE, &debug_isis_lfa_cmd);
3140 install_element(CONFIG_NODE, &no_debug_isis_lfa_cmd);
3141 install_element(CONFIG_NODE, &debug_isis_rtevents_cmd);
3142 install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd);
3143 install_element(CONFIG_NODE, &debug_isis_events_cmd);
3144 install_element(CONFIG_NODE, &no_debug_isis_events_cmd);
3145 install_element(CONFIG_NODE, &debug_isis_packet_dump_cmd);
3146 install_element(CONFIG_NODE, &no_debug_isis_packet_dump_cmd);
3147 install_element(CONFIG_NODE, &debug_isis_lsp_gen_cmd);
3148 install_element(CONFIG_NODE, &no_debug_isis_lsp_gen_cmd);
3149 install_element(CONFIG_NODE, &debug_isis_lsp_sched_cmd);
3150 install_element(CONFIG_NODE, &no_debug_isis_lsp_sched_cmd);
3151 install_element(CONFIG_NODE, &debug_isis_bfd_cmd);
3152 install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd);
3153 install_element(CONFIG_NODE, &debug_isis_ldp_sync_cmd);
3154 install_element(CONFIG_NODE, &no_debug_isis_ldp_sync_cmd);
3155
3156 install_default(ROUTER_NODE);
3157
3158 #ifdef FABRICD
3159 install_element(CONFIG_NODE, &router_openfabric_cmd);
3160 install_element(CONFIG_NODE, &no_router_openfabric_cmd);
3161
3162 install_element(ROUTER_NODE, &net_cmd);
3163 install_element(ROUTER_NODE, &no_net_cmd);
3164
3165 install_element(ROUTER_NODE, &isis_topology_cmd);
3166 install_element(ROUTER_NODE, &no_isis_topology_cmd);
3167
3168 install_element(ROUTER_NODE, &log_adj_changes_cmd);
3169 install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
3170 #endif /* ifdef FABRICD */
3171
3172 spf_backoff_cmd_init();
3173 }