blob: 4b45df1df034b3f85ecd1221d306d68014bff966 [file] [log] [blame]
David Lamparter3732cba2016-07-29 16:19:40 +02001/*
2 * IS-IS Rout(e)ing protocol - isis_circuit.h
3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 * Copyright (C) 2016 David Lamparter, for NetDEF, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <zebra.h>
25#include <command.h>
26
27#include "isis_circuit.h"
28#include "isis_csm.h"
29#include "isis_misc.h"
30#include "isisd.h"
31
32static struct isis_circuit *
33isis_circuit_lookup (struct vty *vty)
34{
35 struct interface *ifp;
36 struct isis_circuit *circuit;
37
38 ifp = (struct interface *) vty->index;
39 if (!ifp)
40 {
41 vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
42 return NULL;
43 }
44
45 circuit = circuit_scan_by_ifp (ifp);
46 if (!circuit)
47 {
48 vty_out (vty, "ISIS is not enabled on circuit %s%s",
49 ifp->name, VTY_NEWLINE);
50 return NULL;
51 }
52
53 return circuit;
54}
55
56DEFUN (ip_router_isis,
57 ip_router_isis_cmd,
58 "(ip|ipv6) router isis WORD",
59 "Interface Internet Protocol config commands\n"
60 "IP router interface commands\n"
61 "IS-IS Routing for IP\n"
62 "Routing process tag\n")
63{
64 struct interface *ifp;
65 struct isis_circuit *circuit;
66 struct isis_area *area;
67 const char *af = argv[0];
68 const char *area_tag = argv[1];
69
70 ifp = (struct interface *) vty->index;
71 assert (ifp);
72
73 /* Prevent more than one area per circuit */
74 circuit = circuit_scan_by_ifp (ifp);
75 if (circuit)
76 {
77 if (circuit->ip_router == 1)
78 {
79 if (strcmp (circuit->area->area_tag, area_tag))
80 {
81 vty_out (vty, "ISIS circuit is already defined on %s%s",
82 circuit->area->area_tag, VTY_NEWLINE);
83 return CMD_ERR_NOTHING_TODO;
84 }
85 return CMD_SUCCESS;
86 }
87 }
88
89 area = isis_area_lookup (area_tag);
90 if (!area)
91 area = isis_area_create (area_tag);
92
93 if (!circuit)
94 circuit = isis_circuit_create (area, ifp);
95
96 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
97 if (af[2] != '\0')
98 ipv6 = true;
99 else
100 ip = true;
101
102 isis_circuit_af_set (circuit, ip, ipv6);
103 return CMD_SUCCESS;
104}
105
106DEFUN (no_ip_router_isis,
107 no_ip_router_isis_cmd,
108 "no (ip|ipv6) router isis WORD",
109 NO_STR
110 "Interface Internet Protocol config commands\n"
111 "IP router interface commands\n"
112 "IS-IS Routing for IP\n"
113 "Routing process tag\n")
114{
115 struct interface *ifp;
116 struct isis_area *area;
117 struct isis_circuit *circuit;
118 const char *af = argv[0];
119 const char *area_tag = argv[1];
120
121 ifp = (struct interface *) vty->index;
122 if (!ifp)
123 {
124 vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
125 return CMD_ERR_NO_MATCH;
126 }
127
128 area = isis_area_lookup (area_tag);
129 if (!area)
130 {
131 vty_out (vty, "Can't find ISIS instance %s%s",
132 argv[0], VTY_NEWLINE);
133 return CMD_ERR_NO_MATCH;
134 }
135
136 circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
137 if (!circuit)
138 {
139 vty_out (vty, "ISIS is not enabled on circuit %s%s",
140 ifp->name, VTY_NEWLINE);
141 return CMD_ERR_NO_MATCH;
142 }
143
144 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
145 if (af[2] != '\0')
146 ipv6 = false;
147 else
148 ip = false;
149
150 isis_circuit_af_set (circuit, ip, ipv6);
151 return CMD_SUCCESS;
152}
153
154DEFUN (isis_passive,
155 isis_passive_cmd,
156 "isis passive",
157 "IS-IS commands\n"
158 "Configure the passive mode for interface\n")
159{
160 struct isis_circuit *circuit = isis_circuit_lookup (vty);
161 if (!circuit)
162 return CMD_ERR_NO_MATCH;
163
164 isis_circuit_passive_set (circuit, 1);
165 return CMD_SUCCESS;
166}
167
168DEFUN (no_isis_passive,
169 no_isis_passive_cmd,
170 "no isis passive",
171 NO_STR
172 "IS-IS commands\n"
173 "Configure the passive mode for interface\n")
174{
175 struct isis_circuit *circuit = isis_circuit_lookup (vty);
176 if (!circuit)
177 return CMD_ERR_NO_MATCH;
178
179 if (if_is_loopback (circuit->interface))
180 {
181 vty_out (vty, "Can't set no passive for loopback interface%s",
182 VTY_NEWLINE);
183 return CMD_ERR_AMBIGUOUS;
184 }
185
186 isis_circuit_passive_set (circuit, 0);
187 return CMD_SUCCESS;
188}
189
190DEFUN (isis_circuit_type,
191 isis_circuit_type_cmd,
192 "isis circuit-type (level-1|level-1-2|level-2-only)",
193 "IS-IS commands\n"
194 "Configure circuit type for interface\n"
195 "Level-1 only adjacencies are formed\n"
196 "Level-1-2 adjacencies are formed\n"
197 "Level-2 only adjacencies are formed\n")
198{
199 int is_type;
200 struct isis_circuit *circuit = isis_circuit_lookup (vty);
201 if (!circuit)
202 return CMD_ERR_NO_MATCH;
203
204 is_type = string2circuit_t (argv[0]);
205 if (!is_type)
206 {
207 vty_out (vty, "Unknown circuit-type %s", VTY_NEWLINE);
208 return CMD_ERR_AMBIGUOUS;
209 }
210
211 if (circuit->state == C_STATE_UP &&
212 circuit->area->is_type != IS_LEVEL_1_AND_2 &&
213 circuit->area->is_type != is_type)
214 {
215 vty_out (vty, "Invalid circuit level for area %s.%s",
216 circuit->area->area_tag, VTY_NEWLINE);
217 return CMD_ERR_AMBIGUOUS;
218 }
219 isis_circuit_is_type_set (circuit, is_type);
220
221 return CMD_SUCCESS;
222}
223
224DEFUN (no_isis_circuit_type,
225 no_isis_circuit_type_cmd,
226 "no isis circuit-type (level-1|level-1-2|level-2-only)",
227 NO_STR
228 "IS-IS commands\n"
229 "Configure circuit type for interface\n"
230 "Level-1 only adjacencies are formed\n"
231 "Level-1-2 adjacencies are formed\n"
232 "Level-2 only adjacencies are formed\n")
233{
234 int is_type;
235 struct isis_circuit *circuit = isis_circuit_lookup (vty);
236 if (!circuit)
237 return CMD_ERR_NO_MATCH;
238
239 /*
240 * Set the circuits level to its default value
241 */
242 if (circuit->state == C_STATE_UP)
243 is_type = circuit->area->is_type;
244 else
245 is_type = IS_LEVEL_1_AND_2;
246 isis_circuit_is_type_set (circuit, is_type);
247
248 return CMD_SUCCESS;
249}
250
251DEFUN (isis_network,
252 isis_network_cmd,
253 "isis network point-to-point",
254 "IS-IS commands\n"
255 "Set network type\n"
256 "point-to-point network type\n")
257{
258 struct isis_circuit *circuit = isis_circuit_lookup (vty);
259 if (!circuit)
260 return CMD_ERR_NO_MATCH;
261
262 if (!isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P))
263 {
264 vty_out (vty, "isis network point-to-point "
265 "is valid only on broadcast interfaces%s",
266 VTY_NEWLINE);
267 return CMD_ERR_AMBIGUOUS;
268 }
269
270 return CMD_SUCCESS;
271}
272
273DEFUN (no_isis_network,
274 no_isis_network_cmd,
275 "no isis network point-to-point",
276 NO_STR
277 "IS-IS commands\n"
278 "Set network type for circuit\n"
279 "point-to-point network type\n")
280{
281 struct isis_circuit *circuit = isis_circuit_lookup (vty);
282 if (!circuit)
283 return CMD_ERR_NO_MATCH;
284
285 if (!isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST))
286 {
287 vty_out (vty, "isis network point-to-point "
288 "is valid only on broadcast interfaces%s",
289 VTY_NEWLINE);
290 return CMD_ERR_AMBIGUOUS;
291 }
292
293 return CMD_SUCCESS;
294}
295
296DEFUN (isis_priority,
297 isis_priority_cmd,
298 "isis priority <0-127>",
299 "IS-IS commands\n"
300 "Set priority for Designated Router election\n"
301 "Priority value\n")
302{
303 int prio;
304 struct isis_circuit *circuit = isis_circuit_lookup (vty);
305 if (!circuit)
306 return CMD_ERR_NO_MATCH;
307
308 prio = atoi (argv[0]);
309 if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
310 {
311 vty_out (vty, "Invalid priority %d - should be <0-127>%s",
312 prio, VTY_NEWLINE);
313 return CMD_ERR_AMBIGUOUS;
314 }
315
316 circuit->priority[0] = prio;
317 circuit->priority[1] = prio;
318
319 return CMD_SUCCESS;
320}
321
322DEFUN (no_isis_priority,
323 no_isis_priority_cmd,
324 "no isis priority",
325 NO_STR
326 "IS-IS commands\n"
327 "Set priority for Designated Router election\n")
328{
329 struct isis_circuit *circuit = isis_circuit_lookup (vty);
330 if (!circuit)
331 return CMD_ERR_NO_MATCH;
332
333 circuit->priority[0] = DEFAULT_PRIORITY;
334 circuit->priority[1] = DEFAULT_PRIORITY;
335
336 return CMD_SUCCESS;
337}
338
339ALIAS (no_isis_priority,
340 no_isis_priority_arg_cmd,
341 "no isis priority <0-127>",
342 NO_STR
343 "IS-IS commands\n"
344 "Set priority for Designated Router election\n"
345 "Priority value\n")
346
347DEFUN (isis_priority_l1,
348 isis_priority_l1_cmd,
349 "isis priority <0-127> level-1",
350 "IS-IS commands\n"
351 "Set priority for Designated Router election\n"
352 "Priority value\n"
353 "Specify priority for level-1 routing\n")
354{
355 int prio;
356 struct isis_circuit *circuit = isis_circuit_lookup (vty);
357 if (!circuit)
358 return CMD_ERR_NO_MATCH;
359
360 prio = atoi (argv[0]);
361 if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
362 {
363 vty_out (vty, "Invalid priority %d - should be <0-127>%s",
364 prio, VTY_NEWLINE);
365 return CMD_ERR_AMBIGUOUS;
366 }
367
368 circuit->priority[0] = prio;
369
370 return CMD_SUCCESS;
371}
372
373DEFUN (no_isis_priority_l1,
374 no_isis_priority_l1_cmd,
375 "no isis priority level-1",
376 NO_STR
377 "IS-IS commands\n"
378 "Set priority for Designated Router election\n"
379 "Specify priority for level-1 routing\n")
380{
381 struct isis_circuit *circuit = isis_circuit_lookup (vty);
382 if (!circuit)
383 return CMD_ERR_NO_MATCH;
384
385 circuit->priority[0] = DEFAULT_PRIORITY;
386
387 return CMD_SUCCESS;
388}
389
390ALIAS (no_isis_priority_l1,
391 no_isis_priority_l1_arg_cmd,
392 "no isis priority <0-127> level-1",
393 NO_STR
394 "IS-IS commands\n"
395 "Set priority for Designated Router election\n"
396 "Priority value\n"
397 "Specify priority for level-1 routing\n")
398
399DEFUN (isis_priority_l2,
400 isis_priority_l2_cmd,
401 "isis priority <0-127> level-2",
402 "IS-IS commands\n"
403 "Set priority for Designated Router election\n"
404 "Priority value\n"
405 "Specify priority for level-2 routing\n")
406{
407 int prio;
408 struct isis_circuit *circuit = isis_circuit_lookup (vty);
409 if (!circuit)
410 return CMD_ERR_NO_MATCH;
411
412 prio = atoi (argv[0]);
413 if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
414 {
415 vty_out (vty, "Invalid priority %d - should be <0-127>%s",
416 prio, VTY_NEWLINE);
417 return CMD_ERR_AMBIGUOUS;
418 }
419
420 circuit->priority[1] = prio;
421
422 return CMD_SUCCESS;
423}
424
425DEFUN (no_isis_priority_l2,
426 no_isis_priority_l2_cmd,
427 "no isis priority level-2",
428 NO_STR
429 "IS-IS commands\n"
430 "Set priority for Designated Router election\n"
431 "Specify priority for level-2 routing\n")
432{
433 struct isis_circuit *circuit = isis_circuit_lookup (vty);
434 if (!circuit)
435 return CMD_ERR_NO_MATCH;
436
437 circuit->priority[1] = DEFAULT_PRIORITY;
438
439 return CMD_SUCCESS;
440}
441
442ALIAS (no_isis_priority_l2,
443 no_isis_priority_l2_arg_cmd,
444 "no isis priority <0-127> level-2",
445 NO_STR
446 "IS-IS commands\n"
447 "Set priority for Designated Router election\n"
448 "Priority value\n"
449 "Specify priority for level-2 routing\n")
450
451/* Metric command */
452DEFUN (isis_metric,
453 isis_metric_cmd,
454 "isis metric <0-16777215>",
455 "IS-IS commands\n"
456 "Set default metric for circuit\n"
457 "Default metric value\n")
458{
459 int met;
460 struct isis_circuit *circuit = isis_circuit_lookup (vty);
461 if (!circuit)
462 return CMD_ERR_NO_MATCH;
463
464 met = atoi (argv[0]);
465
466 /* RFC3787 section 5.1 */
467 if (circuit->area && circuit->area->oldmetric == 1 &&
468 met > MAX_NARROW_LINK_METRIC)
469 {
470 vty_out (vty, "Invalid metric %d - should be <0-63> "
471 "when narrow metric type enabled%s",
472 met, VTY_NEWLINE);
473 return CMD_ERR_AMBIGUOUS;
474 }
475
476 /* RFC4444 */
477 if (circuit->area && circuit->area->newmetric == 1 &&
478 met > MAX_WIDE_LINK_METRIC)
479 {
480 vty_out (vty, "Invalid metric %d - should be <0-16777215> "
481 "when wide metric type enabled%s",
482 met, VTY_NEWLINE);
483 return CMD_ERR_AMBIGUOUS;
484 }
485
486 isis_circuit_metric_set (circuit, IS_LEVEL_1, met);
487 isis_circuit_metric_set (circuit, IS_LEVEL_2, met);
488 return CMD_SUCCESS;
489}
490
491DEFUN (no_isis_metric,
492 no_isis_metric_cmd,
493 "no isis metric",
494 NO_STR
495 "IS-IS commands\n"
496 "Set default metric for circuit\n")
497{
498 struct isis_circuit *circuit = isis_circuit_lookup (vty);
499 if (!circuit)
500 return CMD_ERR_NO_MATCH;
501
502 isis_circuit_metric_set (circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC);
503 isis_circuit_metric_set (circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC);
504 return CMD_SUCCESS;
505}
506
507ALIAS (no_isis_metric,
508 no_isis_metric_arg_cmd,
509 "no isis metric <0-16777215>",
510 NO_STR
511 "IS-IS commands\n"
512 "Set default metric for circuit\n"
513 "Default metric value\n")
514
515DEFUN (isis_metric_l1,
516 isis_metric_l1_cmd,
517 "isis metric <0-16777215> level-1",
518 "IS-IS commands\n"
519 "Set default metric for circuit\n"
520 "Default metric value\n"
521 "Specify metric for level-1 routing\n")
522{
523 int met;
524 struct isis_circuit *circuit = isis_circuit_lookup (vty);
525 if (!circuit)
526 return CMD_ERR_NO_MATCH;
527
528 met = atoi (argv[0]);
529
530 /* RFC3787 section 5.1 */
531 if (circuit->area && circuit->area->oldmetric == 1 &&
532 met > MAX_NARROW_LINK_METRIC)
533 {
534 vty_out (vty, "Invalid metric %d - should be <0-63> "
535 "when narrow metric type enabled%s",
536 met, VTY_NEWLINE);
537 return CMD_ERR_AMBIGUOUS;
538 }
539
540 /* RFC4444 */
541 if (circuit->area && circuit->area->newmetric == 1 &&
542 met > MAX_WIDE_LINK_METRIC)
543 {
544 vty_out (vty, "Invalid metric %d - should be <0-16777215> "
545 "when wide metric type enabled%s",
546 met, VTY_NEWLINE);
547 return CMD_ERR_AMBIGUOUS;
548 }
549
550 isis_circuit_metric_set (circuit, IS_LEVEL_1, met);
551 return CMD_SUCCESS;
552}
553
554DEFUN (no_isis_metric_l1,
555 no_isis_metric_l1_cmd,
556 "no isis metric level-1",
557 NO_STR
558 "IS-IS commands\n"
559 "Set default metric for circuit\n"
560 "Specify metric for level-1 routing\n")
561{
562 struct isis_circuit *circuit = isis_circuit_lookup (vty);
563 if (!circuit)
564 return CMD_ERR_NO_MATCH;
565
566 isis_circuit_metric_set (circuit, IS_LEVEL_1, DEFAULT_CIRCUIT_METRIC);
567 return CMD_SUCCESS;
568}
569
570ALIAS (no_isis_metric_l1,
571 no_isis_metric_l1_arg_cmd,
572 "no isis metric <0-16777215> level-1",
573 NO_STR
574 "IS-IS commands\n"
575 "Set default metric for circuit\n"
576 "Default metric value\n"
577 "Specify metric for level-1 routing\n")
578
579DEFUN (isis_metric_l2,
580 isis_metric_l2_cmd,
581 "isis metric <0-16777215> level-2",
582 "IS-IS commands\n"
583 "Set default metric for circuit\n"
584 "Default metric value\n"
585 "Specify metric for level-2 routing\n")
586{
587 int met;
588 struct isis_circuit *circuit = isis_circuit_lookup (vty);
589 if (!circuit)
590 return CMD_ERR_NO_MATCH;
591
592 met = atoi (argv[0]);
593
594 /* RFC3787 section 5.1 */
595 if (circuit->area && circuit->area->oldmetric == 1 &&
596 met > MAX_NARROW_LINK_METRIC)
597 {
598 vty_out (vty, "Invalid metric %d - should be <0-63> "
599 "when narrow metric type enabled%s",
600 met, VTY_NEWLINE);
601 return CMD_ERR_AMBIGUOUS;
602 }
603
604 /* RFC4444 */
605 if (circuit->area && circuit->area->newmetric == 1 &&
606 met > MAX_WIDE_LINK_METRIC)
607 {
608 vty_out (vty, "Invalid metric %d - should be <0-16777215> "
609 "when wide metric type enabled%s",
610 met, VTY_NEWLINE);
611 return CMD_ERR_AMBIGUOUS;
612 }
613
614 isis_circuit_metric_set (circuit, IS_LEVEL_2, met);
615 return CMD_SUCCESS;
616}
617
618DEFUN (no_isis_metric_l2,
619 no_isis_metric_l2_cmd,
620 "no isis metric level-2",
621 NO_STR
622 "IS-IS commands\n"
623 "Set default metric for circuit\n"
624 "Specify metric for level-2 routing\n")
625{
626 struct isis_circuit *circuit = isis_circuit_lookup (vty);
627 if (!circuit)
628 return CMD_ERR_NO_MATCH;
629
630 isis_circuit_metric_set (circuit, IS_LEVEL_2, DEFAULT_CIRCUIT_METRIC);
631 return CMD_SUCCESS;
632}
633
634ALIAS (no_isis_metric_l2,
635 no_isis_metric_l2_arg_cmd,
636 "no isis metric <0-16777215> level-2",
637 NO_STR
638 "IS-IS commands\n"
639 "Set default metric for circuit\n"
640 "Default metric value\n"
641 "Specify metric for level-2 routing\n")
642/* end of metrics */
643
644void
645isis_vty_init (void)
646{
647 install_element (INTERFACE_NODE, &ip_router_isis_cmd);
648 install_element (INTERFACE_NODE, &no_ip_router_isis_cmd);
649
650 install_element (INTERFACE_NODE, &isis_passive_cmd);
651 install_element (INTERFACE_NODE, &no_isis_passive_cmd);
652
653 install_element (INTERFACE_NODE, &isis_circuit_type_cmd);
654 install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd);
655
656 install_element (INTERFACE_NODE, &isis_network_cmd);
657 install_element (INTERFACE_NODE, &no_isis_network_cmd);
658
659 install_element (INTERFACE_NODE, &isis_priority_cmd);
660 install_element (INTERFACE_NODE, &no_isis_priority_cmd);
661 install_element (INTERFACE_NODE, &no_isis_priority_arg_cmd);
662 install_element (INTERFACE_NODE, &isis_priority_l1_cmd);
663 install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd);
664 install_element (INTERFACE_NODE, &no_isis_priority_l1_arg_cmd);
665 install_element (INTERFACE_NODE, &isis_priority_l2_cmd);
666 install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd);
667 install_element (INTERFACE_NODE, &no_isis_priority_l2_arg_cmd);
668
669 install_element (INTERFACE_NODE, &isis_metric_cmd);
670 install_element (INTERFACE_NODE, &no_isis_metric_cmd);
671 install_element (INTERFACE_NODE, &no_isis_metric_arg_cmd);
672 install_element (INTERFACE_NODE, &isis_metric_l1_cmd);
673 install_element (INTERFACE_NODE, &no_isis_metric_l1_cmd);
674 install_element (INTERFACE_NODE, &no_isis_metric_l1_arg_cmd);
675 install_element (INTERFACE_NODE, &isis_metric_l2_cmd);
676 install_element (INTERFACE_NODE, &no_isis_metric_l2_cmd);
677 install_element (INTERFACE_NODE, &no_isis_metric_l2_arg_cmd);
678}