]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_circuit.c
2005-04-07 Paul Jakma <paul.jakma@sun.com>
[mirror_frr.git] / isisd / isis_circuit.c
1 /*
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 *
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; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <zebra.h>
26 #ifdef GNU_LINUX
27 #include <net/ethernet.h>
28 #else
29 #include <netinet/if_ether.h>
30 #endif
31
32 #include "log.h"
33 #include "memory.h"
34 #include "if.h"
35 #include "linklist.h"
36 #include "command.h"
37 #include "thread.h"
38 #include "hash.h"
39 #include "prefix.h"
40 #include "stream.h"
41
42 #include "isisd/dict.h"
43 #include "isisd/include-netbsd/iso.h"
44 #include "isisd/isis_constants.h"
45 #include "isisd/isis_common.h"
46 #include "isisd/isis_circuit.h"
47 #include "isisd/isis_tlv.h"
48 #include "isisd/isis_lsp.h"
49 #include "isisd/isis_pdu.h"
50 #include "isisd/isis_network.h"
51 #include "isisd/isis_misc.h"
52 #include "isisd/isis_constants.h"
53 #include "isisd/isis_adjacency.h"
54 #include "isisd/isis_dr.h"
55 #include "isisd/isis_flags.h"
56 #include "isisd/isisd.h"
57 #include "isisd/isis_csm.h"
58 #include "isisd/isis_events.h"
59
60 extern struct thread_master *master;
61 extern struct isis *isis;
62
63 struct isis_circuit *
64 isis_circuit_new ()
65 {
66 struct isis_circuit *circuit;
67 int i;
68
69 circuit = XMALLOC (MTYPE_ISIS_CIRCUIT, sizeof (struct isis_circuit));
70 if (circuit)
71 {
72 memset (circuit, 0, sizeof (struct isis_circuit));
73 /* set default metrics for circuit */
74 for (i = 0; i < 2; i++)
75 {
76 circuit->metrics[i].metric_default = DEFAULT_CIRCUIT_METRICS;
77 circuit->metrics[i].metric_expense = METRICS_UNSUPPORTED;
78 circuit->metrics[i].metric_error = METRICS_UNSUPPORTED;
79 circuit->metrics[i].metric_delay = METRICS_UNSUPPORTED;
80 }
81 }
82 else
83 {
84 zlog_err ("Can't malloc isis circuit");
85 return NULL;
86 }
87
88 return circuit;
89 }
90
91 void
92 isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area)
93 {
94 int i;
95 circuit->area = area;
96 /*
97 * The level for the circuit is same as for the area, unless configured
98 * otherwise.
99 */
100 circuit->circuit_is_type = area->is_type;
101 /*
102 * Default values
103 */
104 for (i = 0; i < 2; i++)
105 {
106 circuit->hello_interval[i] = HELLO_INTERVAL;
107 circuit->hello_multiplier[i] = HELLO_MULTIPLIER;
108 circuit->csnp_interval[i] = CSNP_INTERVAL;
109 circuit->psnp_interval[i] = PSNP_INTERVAL;
110 circuit->u.bc.priority[i] = DEFAULT_PRIORITY;
111 }
112 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
113 {
114 circuit->u.bc.adjdb[0] = list_new ();
115 circuit->u.bc.adjdb[1] = list_new ();
116 circuit->u.bc.pad_hellos = 1;
117 }
118 circuit->lsp_interval = LSP_INTERVAL;
119
120 /*
121 * Add the circuit into area
122 */
123 listnode_add (area->circuit_list, circuit);
124
125 circuit->idx = flags_get_index (&area->flags);
126 circuit->lsp_queue = list_new ();
127
128 return;
129 }
130
131 void
132 isis_circuit_deconfigure (struct isis_circuit *circuit,
133 struct isis_area *area)
134 {
135
136 /* Remove circuit from area */
137 listnode_delete (area->circuit_list, circuit);
138 /* Free the index of SRM and SSN flags */
139 flags_free_index (&area->flags, circuit->idx);
140
141 return;
142 }
143
144 struct isis_circuit *
145 circuit_lookup_by_ifp (struct interface *ifp, struct list *list)
146 {
147 struct isis_circuit *circuit = NULL;
148 struct listnode *node;
149
150 if (!list)
151 return NULL;
152
153 for (ALL_LIST_ELEMENTS_RO (list, node, circuit))
154 if (circuit->interface == ifp)
155 return circuit;
156
157 return NULL;
158 }
159
160 struct isis_circuit *
161 circuit_scan_by_ifp (struct interface *ifp)
162 {
163 struct isis_area *area;
164 struct listnode *node;
165 struct isis_circuit *circuit;
166
167 if (!isis->area_list)
168 return NULL;
169
170 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
171 {
172 circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
173 if (circuit)
174 return circuit;
175 }
176
177 return circuit_lookup_by_ifp (ifp, isis->init_circ_list);
178 }
179
180 void
181 isis_circuit_del (struct isis_circuit *circuit)
182 {
183
184 if (!circuit)
185 return;
186
187 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
188 {
189 /* destroy adjacency databases */
190 if (circuit->u.bc.adjdb[0])
191 list_delete (circuit->u.bc.adjdb[0]);
192 if (circuit->u.bc.adjdb[1])
193 list_delete (circuit->u.bc.adjdb[1]);
194 /* destroy neighbour lists */
195 if (circuit->u.bc.lan_neighs[0])
196 list_delete (circuit->u.bc.lan_neighs[0]);
197 if (circuit->u.bc.lan_neighs[1])
198 list_delete (circuit->u.bc.lan_neighs[1]);
199 /* destroy addresses */
200 }
201 if (circuit->ip_addrs)
202 list_delete (circuit->ip_addrs);
203 #ifdef HAVE_IPV6
204 if (circuit->ipv6_link)
205 list_delete (circuit->ipv6_link);
206 if (circuit->ipv6_non_link)
207 list_delete (circuit->ipv6_non_link);
208 #endif /* HAVE_IPV6 */
209
210 /* and lastly the circuit itself */
211 XFREE (MTYPE_ISIS_CIRCUIT, circuit);
212
213 return;
214 }
215
216 void
217 isis_circuit_add_addr (struct isis_circuit *circuit,
218 struct connected *connected)
219 {
220 struct prefix_ipv4 *ipv4;
221 u_char buf[BUFSIZ];
222 #ifdef HAVE_IPV6
223 struct prefix_ipv6 *ipv6;
224 #endif /* HAVE_IPV6 */
225
226 if (!circuit->ip_addrs)
227 circuit->ip_addrs = list_new ();
228 #ifdef HAVE_IPV6
229 if (!circuit->ipv6_link)
230 circuit->ipv6_link = list_new ();
231 if (!circuit->ipv6_non_link)
232 circuit->ipv6_non_link = list_new ();
233 #endif /* HAVE_IPV6 */
234
235 memset (&buf, 0, BUFSIZ);
236 if (connected->address->family == AF_INET)
237 {
238 ipv4 = prefix_ipv4_new ();
239 ipv4->prefixlen = connected->address->prefixlen;
240 ipv4->prefix = connected->address->u.prefix4;
241 listnode_add (circuit->ip_addrs, ipv4);
242 if (circuit->area)
243 lsp_regenerate_schedule (circuit->area);
244
245 #ifdef EXTREME_DEBUG
246 prefix2str (connected->address, buf, BUFSIZ);
247 zlog_debug ("Added IP address %s to circuit %d", buf,
248 circuit->circuit_id);
249 #endif /* EXTREME_DEBUG */
250 }
251 #ifdef HAVE_IPV6
252 if (connected->address->family == AF_INET6)
253 {
254 ipv6 = prefix_ipv6_new ();
255 ipv6->prefixlen = connected->address->prefixlen;
256 ipv6->prefix = connected->address->u.prefix6;
257
258 if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
259 listnode_add (circuit->ipv6_link, ipv6);
260 else
261 listnode_add (circuit->ipv6_non_link, ipv6);
262 if (circuit->area)
263 lsp_regenerate_schedule (circuit->area);
264
265 #ifdef EXTREME_DEBUG
266 prefix2str (connected->address, buf, BUFSIZ);
267 zlog_debug ("Added IPv6 address %s to circuit %d", buf,
268 circuit->circuit_id);
269 #endif /* EXTREME_DEBUG */
270 }
271 #endif /* HAVE_IPV6 */
272 return;
273 }
274
275 void
276 isis_circuit_del_addr (struct isis_circuit *circuit,
277 struct connected *connected)
278 {
279 struct prefix_ipv4 *ipv4, *ip = NULL;
280 struct listnode *node;
281 int found = 0;
282 u_char buf[BUFSIZ];
283 #ifdef HAVE_IPV6
284 struct prefix_ipv6 *ipv6, *ip6 = NULL;
285 #endif /* HAVE_IPV6 */
286
287 memset (&buf, 0, BUFSIZ);
288 if (connected->address->family == AF_INET)
289 {
290 ipv4 = prefix_ipv4_new ();
291 ipv4->prefixlen = connected->address->prefixlen;
292 ipv4->prefix = connected->address->u.prefix4;
293
294 for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip))
295 if (prefix_same ((struct prefix *) ip, (struct prefix *) &ipv4))
296 break;
297
298 if (ip)
299 {
300 listnode_delete (circuit->ip_addrs, ip);
301 if (circuit->area)
302 lsp_regenerate_schedule (circuit->area);
303 }
304 else
305 {
306 prefix2str (connected->address, (char *)buf, BUFSIZ);
307 zlog_warn("Nonexitant ip address %s removal attempt from circuit \
308 %d", buf, circuit->circuit_id);
309 }
310 }
311 #ifdef HAVE_IPV6
312 if (connected->address->family == AF_INET6)
313 {
314 ipv6 = prefix_ipv6_new ();
315 ipv6->prefixlen = connected->address->prefixlen;
316 ipv6->prefix = connected->address->u.prefix6;
317
318 if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
319 {
320 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ip6))
321 {
322 if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
323 break;
324 }
325 if (ip6)
326 {
327 listnode_delete (circuit->ipv6_link, ip6);
328 found = 1;
329 }
330 }
331 else
332 {
333 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ip6))
334 {
335 if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
336 break;
337 }
338 if (ip6)
339 {
340 listnode_delete (circuit->ipv6_non_link, ip6);
341 found = 1;
342 }
343 }
344
345 if (!found)
346 {
347 prefix2str (connected->address, (char *)buf, BUFSIZ);
348 zlog_warn("Nonexitant ip address %s removal attempt from \
349 circuit %d", buf, circuit->circuit_id);
350 }
351 else
352 if (circuit->area)
353 lsp_regenerate_schedule (circuit->area);
354 }
355 #endif /* HAVE_IPV6 */
356 return;
357 }
358
359 void
360 isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
361 {
362 struct listnode *node, *nnode;
363 struct connected *conn;
364
365 circuit->interface = ifp;
366 ifp->info = circuit;
367
368 circuit->circuit_id = ifp->ifindex % 255; /* FIXME: Why not ? */
369
370 /* isis_circuit_update_addrs (circuit, ifp); */
371
372 if (if_is_broadcast (ifp))
373 {
374 circuit->circ_type = CIRCUIT_T_BROADCAST;
375 /*
376 * Get the Hardware Address
377 */
378 #ifdef HAVE_SOCKADDR_DL
379 if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
380 zlog_warn ("unsupported link layer");
381 else
382 memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl),
383 ETH_ALEN);
384 #else
385 if (circuit->interface->hw_addr_len != ETH_ALEN)
386 {
387 zlog_warn ("unsupported link layer");
388 }
389 else
390 {
391 memcpy (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN);
392 }
393 #ifdef EXTREME_DEGUG
394 zlog_debug ("isis_circuit_if_add: if_id %d, isomtu %d snpa %s",
395 circuit->interface->ifindex, ISO_MTU (circuit),
396 snpa_print (circuit->u.bc.snpa));
397
398 #endif /* EXTREME_DEBUG */
399 #endif /* HAVE_SOCKADDR_DL */
400 }
401 else if (if_is_pointopoint (ifp))
402 {
403 circuit->circ_type = CIRCUIT_T_P2P;
404 }
405 else
406 {
407 zlog_warn ("isis_circuit_if_add: unsupported media");
408 }
409
410 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
411 isis_circuit_add_addr (circuit, conn);
412
413 return;
414 }
415
416 void
417 isis_circuit_update_params (struct isis_circuit *circuit,
418 struct interface *ifp)
419 {
420 assert (circuit);
421
422 if (circuit->circuit_id != ifp->ifindex)
423 {
424 zlog_warn ("changing circuit_id %d->%d", circuit->circuit_id,
425 ifp->ifindex);
426 circuit->circuit_id = ifp->ifindex % 255;
427 }
428
429 /* FIXME: Why is this needed? shouldn't we compare to the area's mtu */
430 /* Ofer, this was here in case someone changes the mtu (e.g. with ifconfig)
431 The areas MTU is the minimum of mtu's of circuits in the area
432 now we can't catch the change
433 if (circuit->mtu != ifp->mtu) {
434 zlog_warn ("changing circuit mtu %d->%d", circuit->mtu,
435 ifp->mtu);
436 circuit->mtu = ifp->mtu;
437 }
438 */
439 /*
440 * Get the Hardware Address
441 */
442 #ifdef HAVE_SOCKADDR_DL
443 if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
444 zlog_warn ("unsupported link layer");
445 else
446 memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl), ETH_ALEN);
447 #else
448 if (circuit->interface->hw_addr_len != ETH_ALEN)
449 {
450 zlog_warn ("unsupported link layer");
451 }
452 else
453 {
454 if (memcmp (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN))
455 {
456 zlog_warn ("changing circuit snpa %s->%s",
457 snpa_print (circuit->u.bc.snpa),
458 snpa_print (circuit->interface->hw_addr));
459 }
460 }
461 #endif
462
463 if (if_is_broadcast (ifp))
464 {
465 circuit->circ_type = CIRCUIT_T_BROADCAST;
466 }
467 else if (if_is_pointopoint (ifp))
468 {
469 circuit->circ_type = CIRCUIT_T_P2P;
470 }
471 else
472 {
473 zlog_warn ("isis_circuit_update_params: unsupported media");
474 }
475
476 return;
477 }
478
479 void
480 isis_circuit_if_del (struct isis_circuit *circuit)
481 {
482 circuit->interface->info = NULL;
483 circuit->interface = NULL;
484
485 return;
486 }
487
488 void
489 isis_circuit_up (struct isis_circuit *circuit)
490 {
491
492 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
493 {
494 if (circuit->area->min_bcast_mtu == 0 ||
495 ISO_MTU (circuit) < circuit->area->min_bcast_mtu)
496 circuit->area->min_bcast_mtu = ISO_MTU (circuit);
497 /*
498 * ISO 10589 - 8.4.1 Enabling of broadcast circuits
499 */
500
501 /* initilizing the hello sending threads
502 * for a broadcast IF
503 */
504
505 /* 8.4.1 a) commence sending of IIH PDUs */
506
507 if (circuit->circuit_is_type & IS_LEVEL_1)
508 {
509 thread_add_event (master, send_lan_l1_hello, circuit, 0);
510 circuit->u.bc.lan_neighs[0] = list_new ();
511 }
512
513 if (circuit->circuit_is_type & IS_LEVEL_2)
514 {
515 thread_add_event (master, send_lan_l2_hello, circuit, 0);
516 circuit->u.bc.lan_neighs[1] = list_new ();
517 }
518
519 /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
520 /* 8.4.1 c) FIXME: listen for ESH PDUs */
521
522 /* 8.4.1 d) */
523 /* dr election will commence in... */
524 if (circuit->circuit_is_type & IS_LEVEL_1)
525 THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
526 circuit, 2 * circuit->hello_interval[0]);
527 if (circuit->circuit_is_type & IS_LEVEL_2)
528 THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
529 circuit, 2 * circuit->hello_interval[1]);
530 }
531 else
532 {
533 /* initializing the hello send threads
534 * for a ptp IF
535 */
536 thread_add_event (master, send_p2p_hello, circuit, 0);
537
538 }
539
540 /* initializing PSNP timers */
541 if (circuit->circuit_is_type & IS_LEVEL_1)
542 {
543 THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
544 isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
545 }
546
547 if (circuit->circuit_is_type & IS_LEVEL_2)
548 {
549 THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
550 isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
551 }
552
553 /* initialize the circuit streams */
554 if (circuit->rcv_stream == NULL)
555 circuit->rcv_stream = stream_new (ISO_MTU (circuit));
556
557 if (circuit->snd_stream == NULL)
558 circuit->snd_stream = stream_new (ISO_MTU (circuit));
559
560 /* unified init for circuits */
561 isis_sock_init (circuit);
562
563 #ifdef GNU_LINUX
564 THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
565 circuit->fd);
566 #else
567 THREAD_TIMER_ON (master, circuit->t_read, isis_receive, circuit,
568 circuit->fd);
569 #endif
570 return;
571 }
572
573 void
574 isis_circuit_down (struct isis_circuit *circuit)
575 {
576 /* Cancel all active threads -- FIXME: wrong place */
577 /* HT: Read thread if GNU_LINUX, TIMER thread otherwise. */
578 THREAD_OFF (circuit->t_read);
579 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
580 {
581 THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]);
582 THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]);
583 THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
584 THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
585 }
586 else if (circuit->circ_type == CIRCUIT_T_P2P)
587 {
588 THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
589 }
590 /* close the socket */
591 close (circuit->fd);
592
593 return;
594 }
595
596 void
597 circuit_update_nlpids (struct isis_circuit *circuit)
598 {
599 circuit->nlpids.count = 0;
600
601 if (circuit->ip_router)
602 {
603 circuit->nlpids.nlpids[0] = NLPID_IP;
604 circuit->nlpids.count++;
605 }
606 #ifdef HAVE_IPV6
607 if (circuit->ipv6_router)
608 {
609 circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
610 circuit->nlpids.count++;
611 }
612 #endif /* HAVE_IPV6 */
613 return;
614 }
615
616 int
617 isis_interface_config_write (struct vty *vty)
618 {
619
620 int write = 0;
621 struct listnode *node, *nnode;
622 struct listnode *node2, *nnode2;
623 struct interface *ifp;
624 struct isis_area *area;
625 struct isis_circuit *c;
626 int i;
627
628 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
629 {
630 /* IF name */
631 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
632 write++;
633 /* IF desc */
634 if (ifp->desc)
635 {
636 vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
637 write++;
638 }
639 /* ISIS Circuit */
640 for (ALL_LIST_ELEMENTS (isis->area_list, node2, nnode2, area))
641 {
642 c = circuit_lookup_by_ifp (ifp, area->circuit_list);
643 if (c)
644 {
645 if (c->ip_router)
646 {
647 vty_out (vty, " ip router isis %s%s", area->area_tag,
648 VTY_NEWLINE);
649 write++;
650 }
651 #ifdef HAVE_IPV6
652 if (c->ipv6_router)
653 {
654 vty_out (vty, " ipv6 router isis %s%s", area->area_tag,
655 VTY_NEWLINE);
656 write++;
657 }
658 #endif /* HAVE_IPV6 */
659
660 /* ISIS - circuit type */
661 if (c->circuit_is_type == IS_LEVEL_1)
662 {
663 vty_out (vty, " isis circuit-type level-1%s", VTY_NEWLINE);
664 write++;
665 }
666 else
667 {
668 if (c->circuit_is_type == IS_LEVEL_2)
669 {
670 vty_out (vty, " isis circuit-type level-2-only%s",
671 VTY_NEWLINE);
672 write++;
673 }
674 }
675
676 /* ISIS - CSNP interval - FIXME: compare to cisco */
677 if (c->csnp_interval[0] == c->csnp_interval[1])
678 {
679 if (c->csnp_interval[0] != CSNP_INTERVAL)
680 {
681 vty_out (vty, " isis csnp-interval %d%s",
682 c->csnp_interval[0], VTY_NEWLINE);
683 write++;
684 }
685 }
686 else
687 {
688 for (i = 0; i < 2; i++)
689 {
690 if (c->csnp_interval[1] != CSNP_INTERVAL)
691 {
692 vty_out (vty, " isis csnp-interval %d level-%d%s",
693 c->csnp_interval[1], i + 1, VTY_NEWLINE);
694 write++;
695 }
696 }
697 }
698
699 /* ISIS - Hello padding - Defaults to true so only display if false */
700 if (c->circ_type == CIRCUIT_T_BROADCAST && !c->u.bc.pad_hellos)
701 {
702 vty_out (vty, " no isis hello padding%s", VTY_NEWLINE);
703 write++;
704 }
705
706 /* ISIS - Hello interval - FIXME: compare to cisco */
707 if (c->hello_interval[0] == c->hello_interval[1])
708 {
709 if (c->hello_interval[0] != HELLO_INTERVAL)
710 {
711 vty_out (vty, " isis hello-interval %d%s",
712 c->hello_interval[0], VTY_NEWLINE);
713 write++;
714 }
715 }
716 else
717 {
718 for (i = 0; i < 2; i++)
719 {
720 if (c->hello_interval[i] != HELLO_INTERVAL)
721 {
722 if (c->hello_interval[i] == HELLO_MINIMAL)
723 {
724 vty_out (vty,
725 " isis hello-interval minimal level-%d%s",
726 i + 1, VTY_NEWLINE);
727 }
728 else
729 {
730 vty_out (vty, " isis hello-interval %d level-%d%s",
731 c->hello_interval[i], i + 1, VTY_NEWLINE);
732 }
733 write++;
734 }
735 }
736 }
737
738 /* ISIS - Hello Multiplier */
739 if (c->hello_multiplier[0] == c->hello_multiplier[1])
740 {
741 if (c->hello_multiplier[0] != HELLO_MULTIPLIER)
742 {
743 vty_out (vty, " isis hello-multiplier %d%s",
744 c->hello_multiplier[0], VTY_NEWLINE);
745 write++;
746 }
747 }
748 else
749 {
750 for (i = 0; i < 2; i++)
751 {
752 if (c->hello_multiplier[i] != HELLO_MULTIPLIER)
753 {
754 vty_out (vty, " isis hello-multiplier %d level-%d%s",
755 c->hello_multiplier[i], i + 1, VTY_NEWLINE);
756 write++;
757 }
758 }
759 }
760 /* ISIS - Priority */
761 if (c->circ_type == CIRCUIT_T_BROADCAST)
762 {
763 if (c->u.bc.priority[0] == c->u.bc.priority[1])
764 {
765 if (c->u.bc.priority[0] != DEFAULT_PRIORITY)
766 {
767 vty_out (vty, " isis priority %d%s",
768 c->u.bc.priority[0], VTY_NEWLINE);
769 write++;
770 }
771 }
772 else
773 {
774 for (i = 0; i < 2; i++)
775 {
776 if (c->u.bc.priority[i] != DEFAULT_PRIORITY)
777 {
778 vty_out (vty, " isis priority %d level-%d%s",
779 c->u.bc.priority[i], i + 1, VTY_NEWLINE);
780 write++;
781 }
782 }
783 }
784 }
785 /* ISIS - Metric */
786 if (c->metrics[0].metric_default == c->metrics[1].metric_default)
787 {
788 if (c->metrics[0].metric_default != DEFAULT_CIRCUIT_METRICS)
789 {
790 vty_out (vty, " isis metric %d%s",
791 c->metrics[0].metric_default, VTY_NEWLINE);
792 write++;
793 }
794 }
795 else
796 {
797 for (i = 0; i < 2; i++)
798 {
799 if (c->metrics[i].metric_default != DEFAULT_CIRCUIT_METRICS)
800 {
801 vty_out (vty, " isis metric %d level-%d%s",
802 c->metrics[i].metric_default, i + 1,
803 VTY_NEWLINE);
804 write++;
805 }
806 }
807 }
808
809 }
810 }
811 vty_out (vty, "!%s", VTY_NEWLINE);
812 }
813
814 return write;
815 }
816
817 DEFUN (ip_router_isis,
818 ip_router_isis_cmd,
819 "ip router isis WORD",
820 "Interface Internet Protocol config commands\n"
821 "IP router interface commands\n"
822 "IS-IS Routing for IP\n"
823 "Routing process tag\n")
824 {
825 struct isis_circuit *c;
826 struct interface *ifp;
827 struct isis_area *area;
828
829 ifp = (struct interface *) vty->index;
830 assert (ifp);
831
832 area = isis_area_lookup (argv[0]);
833
834 /* Prevent more than one circuit per interface */
835 if (area)
836 c = circuit_lookup_by_ifp (ifp, area->circuit_list);
837 else
838 c = NULL;
839 if (c && (ifp->info != NULL))
840 {
841 #ifdef HAVE_IPV6
842 if (c->ipv6_router == 0)
843 {
844 #endif /* HAVE_IPV6 */
845 vty_out (vty, "ISIS circuit is already defined%s", VTY_NEWLINE);
846 return CMD_WARNING;
847 #ifdef HAVE_IPV6
848 }
849 #endif /* HAVE_IPV6 */
850 }
851
852 /* this is here for ciscopability */
853 if (!area)
854 {
855 vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
856 return CMD_WARNING;
857 }
858
859 if (!c)
860 {
861 c = circuit_lookup_by_ifp (ifp, isis->init_circ_list);
862 c = isis_csm_state_change (ISIS_ENABLE, c, area);
863 c->interface = ifp; /* this is automatic */
864 ifp->info = c; /* hardly related to the FSM */
865 }
866
867 if (!c)
868 return CMD_WARNING;
869
870 c->ip_router = 1;
871 area->ip_circuits++;
872 circuit_update_nlpids (c);
873
874 vty->node = INTERFACE_NODE;
875
876 return CMD_SUCCESS;
877 }
878
879 DEFUN (no_ip_router_isis,
880 no_ip_router_isis_cmd,
881 "no ip router isis WORD",
882 NO_STR
883 "Interface Internet Protocol config commands\n"
884 "IP router interface commands\n"
885 "IS-IS Routing for IP\n"
886 "Routing process tag\n")
887 {
888 struct isis_circuit *circuit = NULL;
889 struct interface *ifp;
890 struct isis_area *area;
891 struct listnode *node, *nnode;
892
893 ifp = (struct interface *) vty->index;
894 assert (ifp);
895
896 area = isis_area_lookup (argv[0]);
897 if (!area)
898 {
899 vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
900 return CMD_WARNING;
901 }
902 for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
903 if (circuit->interface == ifp)
904 break;
905 if (!circuit)
906 {
907 vty_out (vty, "Can't find ISIS interface %s", VTY_NEWLINE);
908 return CMD_WARNING;
909 }
910 circuit->ip_router = 0;
911 area->ip_circuits--;
912 #ifdef HAVE_IPV6
913 if (circuit->ipv6_router == 0)
914 #endif
915 isis_csm_state_change (ISIS_DISABLE, circuit, area);
916
917 return CMD_SUCCESS;
918 }
919
920 DEFUN (isis_circuit_type,
921 isis_circuit_type_cmd,
922 "isis circuit-type (level-1|level-1-2|level-2-only)",
923 "IS-IS commands\n"
924 "Configure circuit type for interface\n"
925 "Level-1 only adjacencies are formed\n"
926 "Level-1-2 adjacencies are formed\n"
927 "Level-2 only adjacencies are formed\n")
928 {
929 struct isis_circuit *circuit;
930 struct interface *ifp;
931 int circuit_t;
932 int is_type;
933
934 ifp = vty->index;
935 circuit = ifp->info;
936 /* UGLY - will remove l8r */
937 if (circuit == NULL)
938 {
939 return CMD_WARNING;
940 }
941
942 /* XXX what to do when ip_router_isis is not executed */
943 if (circuit->area == NULL)
944 return CMD_WARNING;
945
946 assert (circuit);
947
948 circuit_t = string2circuit_t ((u_char *)argv[0]);
949
950 if (!circuit_t)
951 {
952 vty_out (vty, "Unknown circuit-type %s", VTY_NEWLINE);
953 return CMD_SUCCESS;
954 }
955
956 is_type = circuit->area->is_type;
957 if (is_type == IS_LEVEL_1_AND_2 || is_type == circuit_t)
958 isis_event_circuit_type_change (circuit, circuit_t);
959 else
960 {
961 vty_out (vty, "invalid circuit level for area %s.%s",
962 circuit->area->area_tag, VTY_NEWLINE);
963 }
964
965 return CMD_SUCCESS;
966 }
967
968 DEFUN (no_isis_circuit_type,
969 no_isis_circuit_type_cmd,
970 "no isis circuit-type (level-1|level-1-2|level-2-only)",
971 NO_STR
972 "IS-IS commands\n"
973 "Configure circuit type for interface\n"
974 "Level-1 only adjacencies are formed\n"
975 "Level-1-2 adjacencies are formed\n"
976 "Level-2 only adjacencies are formed\n")
977 {
978 struct isis_circuit *circuit;
979 struct interface *ifp;
980
981 ifp = vty->index;
982 circuit = ifp->info;
983 if (circuit == NULL)
984 {
985 return CMD_WARNING;
986 }
987
988 assert (circuit);
989
990 /*
991 * Set the circuits level to its default value which is that of the area
992 */
993 isis_event_circuit_type_change (circuit, circuit->area->is_type);
994
995 return CMD_SUCCESS;
996 }
997
998 DEFUN (isis_passwd,
999 isis_passwd_cmd,
1000 "isis password WORD",
1001 "IS-IS commands\n"
1002 "Configure the authentication password for interface\n"
1003 "Password\n")
1004 {
1005 struct isis_circuit *circuit;
1006 struct interface *ifp;
1007 int len;
1008
1009 ifp = vty->index;
1010 circuit = ifp->info;
1011 if (circuit == NULL)
1012 {
1013 return CMD_WARNING;
1014 }
1015
1016 len = strlen (argv[0]);
1017 if (len > 254)
1018 {
1019 vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
1020 return CMD_WARNING;
1021 }
1022 circuit->passwd.len = len;
1023 circuit->passwd.type = ISIS_PASSWD_TYPE_CLEARTXT;
1024 strncpy ((char *)circuit->passwd.passwd, argv[0], 255);
1025
1026 return CMD_SUCCESS;
1027 }
1028
1029 DEFUN (no_isis_passwd,
1030 no_isis_passwd_cmd,
1031 "no isis password",
1032 NO_STR
1033 "IS-IS commands\n"
1034 "Configure the authentication password for interface\n")
1035 {
1036 struct isis_circuit *circuit;
1037 struct interface *ifp;
1038
1039 ifp = vty->index;
1040 circuit = ifp->info;
1041 if (circuit == NULL)
1042 {
1043 return CMD_WARNING;
1044 }
1045
1046 memset (&circuit->passwd, 0, sizeof (struct isis_passwd));
1047
1048 return CMD_SUCCESS;
1049 }
1050
1051
1052 DEFUN (isis_priority,
1053 isis_priority_cmd,
1054 "isis priority <0-127>",
1055 "IS-IS commands\n"
1056 "Set priority for Designated Router election\n"
1057 "Priority value\n")
1058 {
1059 struct isis_circuit *circuit;
1060 struct interface *ifp;
1061 int prio;
1062
1063 ifp = vty->index;
1064 circuit = ifp->info;
1065 if (circuit == NULL)
1066 {
1067 return CMD_WARNING;
1068 }
1069 assert (circuit);
1070
1071 prio = atoi (argv[0]);
1072
1073 circuit->u.bc.priority[0] = prio;
1074 circuit->u.bc.priority[1] = prio;
1075
1076 return CMD_SUCCESS;
1077 }
1078
1079 DEFUN (no_isis_priority,
1080 no_isis_priority_cmd,
1081 "no isis priority",
1082 NO_STR
1083 "IS-IS commands\n"
1084 "Set priority for Designated Router election\n")
1085 {
1086 struct isis_circuit *circuit;
1087 struct interface *ifp;
1088
1089 ifp = vty->index;
1090 circuit = ifp->info;
1091 if (circuit == NULL)
1092 {
1093 return CMD_WARNING;
1094 }
1095 assert (circuit);
1096
1097 circuit->u.bc.priority[0] = DEFAULT_PRIORITY;
1098 circuit->u.bc.priority[1] = DEFAULT_PRIORITY;
1099
1100 return CMD_SUCCESS;
1101 }
1102
1103 ALIAS (no_isis_priority,
1104 no_isis_priority_arg_cmd,
1105 "no isis priority <0-127>",
1106 NO_STR
1107 "IS-IS commands\n"
1108 "Set priority for Designated Router election\n"
1109 "Priority value\n")
1110
1111 DEFUN (isis_priority_l1,
1112 isis_priority_l1_cmd,
1113 "isis priority <0-127> level-1",
1114 "IS-IS commands\n"
1115 "Set priority for Designated Router election\n"
1116 "Priority value\n"
1117 "Specify priority for level-1 routing\n")
1118 {
1119 struct isis_circuit *circuit;
1120 struct interface *ifp;
1121 int prio;
1122
1123 ifp = vty->index;
1124 circuit = ifp->info;
1125 if (circuit == NULL)
1126 {
1127 return CMD_WARNING;
1128 }
1129 assert (circuit);
1130
1131 prio = atoi (argv[0]);
1132
1133 circuit->u.bc.priority[0] = prio;
1134
1135 return CMD_SUCCESS;
1136 }
1137
1138 DEFUN (no_isis_priority_l1,
1139 no_isis_priority_l1_cmd,
1140 "no isis priority level-1",
1141 NO_STR
1142 "IS-IS commands\n"
1143 "Set priority for Designated Router election\n"
1144 "Specify priority for level-1 routing\n")
1145 {
1146 struct isis_circuit *circuit;
1147 struct interface *ifp;
1148
1149 ifp = vty->index;
1150 circuit = ifp->info;
1151 if (circuit == NULL)
1152 {
1153 return CMD_WARNING;
1154 }
1155 assert (circuit);
1156
1157 circuit->u.bc.priority[0] = DEFAULT_PRIORITY;
1158
1159 return CMD_SUCCESS;
1160 }
1161
1162 ALIAS (no_isis_priority_l1,
1163 no_isis_priority_l1_arg_cmd,
1164 "no isis priority <0-127> level-1",
1165 NO_STR
1166 "IS-IS commands\n"
1167 "Set priority for Designated Router election\n"
1168 "Priority value\n"
1169 "Specify priority for level-1 routing\n")
1170
1171 DEFUN (isis_priority_l2,
1172 isis_priority_l2_cmd,
1173 "isis priority <0-127> level-2",
1174 "IS-IS commands\n"
1175 "Set priority for Designated Router election\n"
1176 "Priority value\n"
1177 "Specify priority for level-2 routing\n")
1178 {
1179 struct isis_circuit *circuit;
1180 struct interface *ifp;
1181 int prio;
1182
1183 ifp = vty->index;
1184 circuit = ifp->info;
1185 if (circuit == NULL)
1186 {
1187 return CMD_WARNING;
1188 }
1189 assert (circuit);
1190
1191 prio = atoi (argv[0]);
1192
1193 circuit->u.bc.priority[1] = prio;
1194
1195 return CMD_SUCCESS;
1196 }
1197
1198 DEFUN (no_isis_priority_l2,
1199 no_isis_priority_l2_cmd,
1200 "no isis priority level-2",
1201 NO_STR
1202 "IS-IS commands\n"
1203 "Set priority for Designated Router election\n"
1204 "Specify priority for level-2 routing\n")
1205 {
1206 struct isis_circuit *circuit;
1207 struct interface *ifp;
1208
1209 ifp = vty->index;
1210 circuit = ifp->info;
1211 if (circuit == NULL)
1212 {
1213 return CMD_WARNING;
1214 }
1215 assert (circuit);
1216
1217 circuit->u.bc.priority[1] = DEFAULT_PRIORITY;
1218
1219 return CMD_SUCCESS;
1220 }
1221
1222 ALIAS (no_isis_priority_l2,
1223 no_isis_priority_l2_arg_cmd,
1224 "no isis priority <0-127> level-2",
1225 NO_STR
1226 "IS-IS commands\n"
1227 "Set priority for Designated Router election\n"
1228 "Priority value\n"
1229 "Specify priority for level-2 routing\n")
1230
1231 /* Metric command */
1232 DEFUN (isis_metric,
1233 isis_metric_cmd,
1234 "isis metric <0-63>",
1235 "IS-IS commands\n"
1236 "Set default metric for circuit\n"
1237 "Default metric value\n")
1238 {
1239 struct isis_circuit *circuit;
1240 struct interface *ifp;
1241 int met;
1242
1243 ifp = vty->index;
1244 circuit = ifp->info;
1245 if (circuit == NULL)
1246 {
1247 return CMD_WARNING;
1248 }
1249 assert (circuit);
1250
1251 met = atoi (argv[0]);
1252
1253 circuit->metrics[0].metric_default = met;
1254 circuit->metrics[1].metric_default = met;
1255
1256 return CMD_SUCCESS;
1257 }
1258
1259 DEFUN (no_isis_metric,
1260 no_isis_metric_cmd,
1261 "no isis metric",
1262 NO_STR
1263 "IS-IS commands\n"
1264 "Set default metric for circuit\n")
1265 {
1266 struct isis_circuit *circuit;
1267 struct interface *ifp;
1268
1269 ifp = vty->index;
1270 circuit = ifp->info;
1271 if (circuit == NULL)
1272 {
1273 return CMD_WARNING;
1274 }
1275 assert (circuit);
1276
1277 circuit->metrics[0].metric_default = DEFAULT_CIRCUIT_METRICS;
1278 circuit->metrics[1].metric_default = DEFAULT_CIRCUIT_METRICS;
1279
1280 return CMD_SUCCESS;
1281 }
1282
1283 ALIAS (no_isis_metric,
1284 no_isis_metric_arg_cmd,
1285 "no isis metric <0-127>",
1286 NO_STR
1287 "IS-IS commands\n"
1288 "Set default metric for circuit\n"
1289 "Default metric value\n")
1290
1291 /* end of metrics */
1292 DEFUN (isis_hello_interval,
1293 isis_hello_interval_cmd,
1294 "isis hello-interval (<1-65535>|minimal)",
1295 "IS-IS commands\n"
1296 "Set Hello interval\n"
1297 "Hello interval value\n"
1298 "Holdtime 1 seconds, interval depends on multiplier\n")
1299 {
1300 struct isis_circuit *circuit;
1301 struct interface *ifp;
1302 int interval;
1303 char c;
1304
1305 ifp = vty->index;
1306 circuit = ifp->info;
1307 if (circuit == NULL)
1308 {
1309 return CMD_WARNING;
1310 }
1311 assert (circuit);
1312 c = *argv[0];
1313 if (isdigit ((int) c))
1314 {
1315 interval = atoi (argv[0]);
1316 }
1317 else
1318 interval = HELLO_MINIMAL; /* FIXME: should be calculated */
1319
1320 circuit->hello_interval[0] = (u_int16_t) interval;
1321 circuit->hello_interval[1] = (u_int16_t) interval;
1322
1323 return CMD_SUCCESS;
1324 }
1325
1326 DEFUN (no_isis_hello_interval,
1327 no_isis_hello_interval_cmd,
1328 "no isis hello-interval",
1329 NO_STR
1330 "IS-IS commands\n"
1331 "Set Hello interval\n")
1332 {
1333 struct isis_circuit *circuit;
1334 struct interface *ifp;
1335
1336 ifp = vty->index;
1337 circuit = ifp->info;
1338 if (circuit == NULL)
1339 {
1340 return CMD_WARNING;
1341 }
1342 assert (circuit);
1343
1344
1345 circuit->hello_interval[0] = HELLO_INTERVAL; /* Default is 1 sec. */
1346 circuit->hello_interval[1] = HELLO_INTERVAL;
1347
1348 return CMD_SUCCESS;
1349 }
1350
1351 ALIAS (no_isis_hello_interval,
1352 no_isis_hello_interval_arg_cmd,
1353 "no isis hello-interval (<1-65535>|minimal)",
1354 NO_STR
1355 "IS-IS commands\n"
1356 "Set Hello interval\n"
1357 "Hello interval value\n"
1358 "Holdtime 1 second, interval depends on multiplier\n")
1359
1360 DEFUN (isis_hello_interval_l1,
1361 isis_hello_interval_l1_cmd,
1362 "isis hello-interval (<1-65535>|minimal) level-1",
1363 "IS-IS commands\n"
1364 "Set Hello interval\n"
1365 "Hello interval value\n"
1366 "Holdtime 1 second, interval depends on multiplier\n"
1367 "Specify hello-interval for level-1 IIHs\n")
1368 {
1369 struct isis_circuit *circuit;
1370 struct interface *ifp;
1371 long interval;
1372 char c;
1373
1374 ifp = vty->index;
1375 circuit = ifp->info;
1376 if (circuit == NULL)
1377 {
1378 return CMD_WARNING;
1379 }
1380 assert (circuit);
1381
1382 c = *argv[0];
1383 if (isdigit ((int) c))
1384 {
1385 interval = atoi (argv[0]);
1386 }
1387 else
1388 interval = HELLO_MINIMAL;
1389
1390 circuit->hello_interval[0] = (u_int16_t) interval;
1391
1392 return CMD_SUCCESS;
1393 }
1394
1395 DEFUN (no_isis_hello_interval_l1,
1396 no_isis_hello_interval_l1_cmd,
1397 "no isis hello-interval level-1",
1398 NO_STR
1399 "IS-IS commands\n"
1400 "Set Hello interval\n"
1401 "Specify hello-interval for level-1 IIHs\n")
1402 {
1403 struct isis_circuit *circuit;
1404 struct interface *ifp;
1405
1406 ifp = vty->index;
1407 circuit = ifp->info;
1408 if (circuit == NULL)
1409 {
1410 return CMD_WARNING;
1411 }
1412 assert (circuit);
1413
1414
1415 circuit->hello_interval[0] = HELLO_INTERVAL; /* Default is 1 sec. */
1416
1417 return CMD_SUCCESS;
1418 }
1419
1420 ALIAS (no_isis_hello_interval_l1,
1421 no_isis_hello_interval_l1_arg_cmd,
1422 "no isis hello-interval (<1-65535>|minimal) level-1",
1423 NO_STR
1424 "IS-IS commands\n"
1425 "Set Hello interval\n"
1426 "Hello interval value\n"
1427 "Holdtime 1 second, interval depends on multiplier\n"
1428 "Specify hello-interval for level-1 IIHs\n")
1429
1430 DEFUN (isis_hello_interval_l2,
1431 isis_hello_interval_l2_cmd,
1432 "isis hello-interval (<1-65535>|minimal) level-2",
1433 "IS-IS commands\n"
1434 "Set Hello interval\n"
1435 "Hello interval value\n"
1436 "Holdtime 1 second, interval depends on multiplier\n"
1437 "Specify hello-interval for level-2 IIHs\n")
1438 {
1439 struct isis_circuit *circuit;
1440 struct interface *ifp;
1441 long interval;
1442 char c;
1443
1444 ifp = vty->index;
1445 circuit = ifp->info;
1446 if (circuit == NULL)
1447 {
1448 return CMD_WARNING;
1449 }
1450 assert (circuit);
1451
1452 c = *argv[0];
1453 if (isdigit ((int) c))
1454 {
1455 interval = atoi (argv[0]);
1456 }
1457 else
1458 interval = HELLO_MINIMAL;
1459
1460 circuit->hello_interval[1] = (u_int16_t) interval;
1461
1462 return CMD_SUCCESS;
1463 }
1464
1465 DEFUN (no_isis_hello_interval_l2,
1466 no_isis_hello_interval_l2_cmd,
1467 "no isis hello-interval level-2",
1468 NO_STR
1469 "IS-IS commands\n"
1470 "Set Hello interval\n"
1471 "Specify hello-interval for level-2 IIHs\n")
1472 {
1473 struct isis_circuit *circuit;
1474 struct interface *ifp;
1475
1476 ifp = vty->index;
1477 circuit = ifp->info;
1478 if (circuit == NULL)
1479 {
1480 return CMD_WARNING;
1481 }
1482 assert (circuit);
1483
1484
1485 circuit->hello_interval[1] = HELLO_INTERVAL; /* Default is 1 sec. */
1486
1487 return CMD_SUCCESS;
1488 }
1489
1490 ALIAS (no_isis_hello_interval_l2,
1491 no_isis_hello_interval_l2_arg_cmd,
1492 "no isis hello-interval (<1-65535>|minimal) level-2",
1493 NO_STR
1494 "IS-IS commands\n"
1495 "Set Hello interval\n"
1496 "Hello interval value\n"
1497 "Holdtime 1 second, interval depends on multiplier\n"
1498 "Specify hello-interval for level-2 IIHs\n")
1499
1500 DEFUN (isis_hello_multiplier,
1501 isis_hello_multiplier_cmd,
1502 "isis hello-multiplier <3-1000>",
1503 "IS-IS commands\n"
1504 "Set multiplier for Hello holding time\n"
1505 "Hello multiplier value\n")
1506 {
1507 struct isis_circuit *circuit;
1508 struct interface *ifp;
1509 int mult;
1510
1511 ifp = vty->index;
1512 circuit = ifp->info;
1513 if (circuit == NULL)
1514 {
1515 return CMD_WARNING;
1516 }
1517 assert (circuit);
1518
1519 mult = atoi (argv[0]);
1520
1521 circuit->hello_multiplier[0] = (u_int16_t) mult;
1522 circuit->hello_multiplier[1] = (u_int16_t) mult;
1523
1524 return CMD_SUCCESS;
1525 }
1526
1527 DEFUN (no_isis_hello_multiplier,
1528 no_isis_hello_multiplier_cmd,
1529 "no isis hello-multiplier",
1530 NO_STR
1531 "IS-IS commands\n"
1532 "Set multiplier for Hello holding time\n")
1533 {
1534 struct isis_circuit *circuit;
1535 struct interface *ifp;
1536
1537 ifp = vty->index;
1538 circuit = ifp->info;
1539 if (circuit == NULL)
1540 {
1541 return CMD_WARNING;
1542 }
1543 assert (circuit);
1544
1545 circuit->hello_multiplier[0] = HELLO_MULTIPLIER;
1546 circuit->hello_multiplier[1] = HELLO_MULTIPLIER;
1547
1548 return CMD_SUCCESS;
1549 }
1550
1551 ALIAS (no_isis_hello_multiplier,
1552 no_isis_hello_multiplier_arg_cmd,
1553 "no isis hello-multiplier <3-1000>",
1554 NO_STR
1555 "IS-IS commands\n"
1556 "Set multiplier for Hello holding time\n"
1557 "Hello multiplier value\n")
1558
1559 DEFUN (isis_hello_multiplier_l1,
1560 isis_hello_multiplier_l1_cmd,
1561 "isis hello-multiplier <3-1000> level-1",
1562 "IS-IS commands\n"
1563 "Set multiplier for Hello holding time\n"
1564 "Hello multiplier value\n"
1565 "Specify hello multiplier for level-1 IIHs\n")
1566 {
1567 struct isis_circuit *circuit;
1568 struct interface *ifp;
1569 int mult;
1570
1571 ifp = vty->index;
1572 circuit = ifp->info;
1573 if (circuit == NULL)
1574 {
1575 return CMD_WARNING;
1576 }
1577 assert (circuit);
1578
1579 mult = atoi (argv[0]);
1580
1581 circuit->hello_multiplier[0] = (u_int16_t) mult;
1582
1583 return CMD_SUCCESS;
1584 }
1585
1586 DEFUN (no_isis_hello_multiplier_l1,
1587 no_isis_hello_multiplier_l1_cmd,
1588 "no isis hello-multiplier level-1",
1589 NO_STR
1590 "IS-IS commands\n"
1591 "Set multiplier for Hello holding time\n"
1592 "Specify hello multiplier for level-1 IIHs\n")
1593 {
1594 struct isis_circuit *circuit;
1595 struct interface *ifp;
1596
1597 ifp = vty->index;
1598 circuit = ifp->info;
1599 if (circuit == NULL)
1600 {
1601 return CMD_WARNING;
1602 }
1603 assert (circuit);
1604
1605 circuit->hello_multiplier[0] = HELLO_MULTIPLIER;
1606
1607 return CMD_SUCCESS;
1608 }
1609
1610 ALIAS (no_isis_hello_multiplier_l1,
1611 no_isis_hello_multiplier_l1_arg_cmd,
1612 "no isis hello-multiplier <3-1000> level-1",
1613 NO_STR
1614 "IS-IS commands\n"
1615 "Set multiplier for Hello holding time\n"
1616 "Hello multiplier value\n"
1617 "Specify hello multiplier for level-1 IIHs\n")
1618
1619 DEFUN (isis_hello_multiplier_l2,
1620 isis_hello_multiplier_l2_cmd,
1621 "isis hello-multiplier <3-1000> level-2",
1622 "IS-IS commands\n"
1623 "Set multiplier for Hello holding time\n"
1624 "Hello multiplier value\n"
1625 "Specify hello multiplier for level-2 IIHs\n")
1626 {
1627 struct isis_circuit *circuit;
1628 struct interface *ifp;
1629 int mult;
1630
1631 ifp = vty->index;
1632 circuit = ifp->info;
1633 if (circuit == NULL)
1634 {
1635 return CMD_WARNING;
1636 }
1637 assert (circuit);
1638
1639 mult = atoi (argv[0]);
1640
1641 circuit->hello_multiplier[1] = (u_int16_t) mult;
1642
1643 return CMD_SUCCESS;
1644 }
1645
1646 DEFUN (no_isis_hello_multiplier_l2,
1647 no_isis_hello_multiplier_l2_cmd,
1648 "no isis hello-multiplier level-2",
1649 NO_STR
1650 "IS-IS commands\n"
1651 "Set multiplier for Hello holding time\n"
1652 "Specify hello multiplier for level-2 IIHs\n")
1653 {
1654 struct isis_circuit *circuit;
1655 struct interface *ifp;
1656
1657 ifp = vty->index;
1658 circuit = ifp->info;
1659 if (circuit == NULL)
1660 {
1661 return CMD_WARNING;
1662 }
1663 assert (circuit);
1664
1665 circuit->hello_multiplier[1] = HELLO_MULTIPLIER;
1666
1667 return CMD_SUCCESS;
1668 }
1669
1670 ALIAS (no_isis_hello_multiplier_l2,
1671 no_isis_hello_multiplier_l2_arg_cmd,
1672 "no isis hello-multiplier <3-1000> level-2",
1673 NO_STR
1674 "IS-IS commands\n"
1675 "Set multiplier for Hello holding time\n"
1676 "Hello multiplier value\n"
1677 "Specify hello multiplier for level-2 IIHs\n")
1678
1679 DEFUN (isis_hello,
1680 isis_hello_cmd,
1681 "isis hello padding",
1682 "IS-IS commands\n"
1683 "Add padding to IS-IS hello packets\n"
1684 "Pad hello packets\n"
1685 "<cr>\n")
1686 {
1687 struct interface *ifp;
1688 struct isis_circuit *circuit;
1689
1690 ifp = vty->index;
1691 circuit = ifp->info;
1692 if (circuit == NULL)
1693 {
1694 return CMD_WARNING;
1695 }
1696 assert (circuit);
1697
1698 circuit->u.bc.pad_hellos = 1;
1699
1700 return CMD_SUCCESS;
1701 }
1702
1703 DEFUN (no_isis_hello,
1704 no_isis_hello_cmd,
1705 "no isis hello padding",
1706 NO_STR
1707 "IS-IS commands\n"
1708 "Add padding to IS-IS hello packets\n"
1709 "Pad hello packets\n"
1710 "<cr>\n")
1711 {
1712 struct isis_circuit *circuit;
1713 struct interface *ifp;
1714
1715 ifp = vty->index;
1716 circuit = ifp->info;
1717 if (circuit == NULL)
1718 {
1719 return CMD_WARNING;
1720 }
1721 assert (circuit);
1722
1723 circuit->u.bc.pad_hellos = 0;
1724
1725 return CMD_SUCCESS;
1726 }
1727
1728 DEFUN (csnp_interval,
1729 csnp_interval_cmd,
1730 "isis csnp-interval <0-65535>",
1731 "IS-IS commands\n"
1732 "Set CSNP interval in seconds\n"
1733 "CSNP interval value\n")
1734 {
1735 struct isis_circuit *circuit;
1736 struct interface *ifp;
1737 unsigned long interval;
1738
1739 ifp = vty->index;
1740 circuit = ifp->info;
1741 if (circuit == NULL)
1742 {
1743 return CMD_WARNING;
1744 }
1745 assert (circuit);
1746
1747 interval = atol (argv[0]);
1748
1749 circuit->csnp_interval[0] = (u_int16_t) interval;
1750 circuit->csnp_interval[1] = (u_int16_t) interval;
1751
1752 return CMD_SUCCESS;
1753 }
1754
1755 DEFUN (no_csnp_interval,
1756 no_csnp_interval_cmd,
1757 "no isis csnp-interval",
1758 NO_STR
1759 "IS-IS commands\n"
1760 "Set CSNP interval in seconds\n")
1761 {
1762 struct isis_circuit *circuit;
1763 struct interface *ifp;
1764
1765 ifp = vty->index;
1766 circuit = ifp->info;
1767 if (circuit == NULL)
1768 {
1769 return CMD_WARNING;
1770 }
1771 assert (circuit);
1772
1773 circuit->csnp_interval[0] = CSNP_INTERVAL;
1774 circuit->csnp_interval[1] = CSNP_INTERVAL;
1775
1776 return CMD_SUCCESS;
1777 }
1778
1779 ALIAS (no_csnp_interval,
1780 no_csnp_interval_arg_cmd,
1781 "no isis csnp-interval <0-65535>",
1782 NO_STR
1783 "IS-IS commands\n"
1784 "Set CSNP interval in seconds\n"
1785 "CSNP interval value\n")
1786
1787 DEFUN (csnp_interval_l1,
1788 csnp_interval_l1_cmd,
1789 "isis csnp-interval <0-65535> level-1",
1790 "IS-IS commands\n"
1791 "Set CSNP interval in seconds\n"
1792 "CSNP interval value\n"
1793 "Specify interval for level-1 CSNPs\n")
1794 {
1795 struct isis_circuit *circuit;
1796 struct interface *ifp;
1797 unsigned long interval;
1798
1799 ifp = vty->index;
1800 circuit = ifp->info;
1801 if (circuit == NULL)
1802 {
1803 return CMD_WARNING;
1804 }
1805 assert (circuit);
1806
1807 interval = atol (argv[0]);
1808
1809 circuit->csnp_interval[0] = (u_int16_t) interval;
1810
1811 return CMD_SUCCESS;
1812 }
1813
1814 DEFUN (no_csnp_interval_l1,
1815 no_csnp_interval_l1_cmd,
1816 "no isis csnp-interval level-1",
1817 NO_STR
1818 "IS-IS commands\n"
1819 "Set CSNP interval in seconds\n"
1820 "Specify interval for level-1 CSNPs\n")
1821 {
1822 struct isis_circuit *circuit;
1823 struct interface *ifp;
1824
1825 ifp = vty->index;
1826 circuit = ifp->info;
1827 if (circuit == NULL)
1828 {
1829 return CMD_WARNING;
1830 }
1831 assert (circuit);
1832
1833 circuit->csnp_interval[0] = CSNP_INTERVAL;
1834
1835 return CMD_SUCCESS;
1836 }
1837
1838 ALIAS (no_csnp_interval_l1,
1839 no_csnp_interval_l1_arg_cmd,
1840 "no isis csnp-interval <0-65535> level-1",
1841 NO_STR
1842 "IS-IS commands\n"
1843 "Set CSNP interval in seconds\n"
1844 "CSNP interval value\n"
1845 "Specify interval for level-1 CSNPs\n")
1846
1847 DEFUN (csnp_interval_l2,
1848 csnp_interval_l2_cmd,
1849 "isis csnp-interval <0-65535> level-2",
1850 "IS-IS commands\n"
1851 "Set CSNP interval in seconds\n"
1852 "CSNP interval value\n"
1853 "Specify interval for level-2 CSNPs\n")
1854 {
1855 struct isis_circuit *circuit;
1856 struct interface *ifp;
1857 unsigned long interval;
1858
1859 ifp = vty->index;
1860 circuit = ifp->info;
1861 if (circuit == NULL)
1862 {
1863 return CMD_WARNING;
1864 }
1865 assert (circuit);
1866
1867 interval = atol (argv[0]);
1868
1869 circuit->csnp_interval[1] = (u_int16_t) interval;
1870
1871 return CMD_SUCCESS;
1872 }
1873
1874 DEFUN (no_csnp_interval_l2,
1875 no_csnp_interval_l2_cmd,
1876 "no isis csnp-interval level-2",
1877 NO_STR
1878 "IS-IS commands\n"
1879 "Set CSNP interval in seconds\n"
1880 "Specify interval for level-2 CSNPs\n")
1881 {
1882 struct isis_circuit *circuit;
1883 struct interface *ifp;
1884
1885 ifp = vty->index;
1886 circuit = ifp->info;
1887 if (circuit == NULL)
1888 {
1889 return CMD_WARNING;
1890 }
1891 assert (circuit);
1892
1893 circuit->csnp_interval[1] = CSNP_INTERVAL;
1894
1895 return CMD_SUCCESS;
1896 }
1897
1898 ALIAS (no_csnp_interval_l2,
1899 no_csnp_interval_l2_arg_cmd,
1900 "no isis csnp-interval <0-65535> level-2",
1901 NO_STR
1902 "IS-IS commands\n"
1903 "Set CSNP interval in seconds\n"
1904 "CSNP interval value\n"
1905 "Specify interval for level-2 CSNPs\n")
1906
1907 #ifdef HAVE_IPV6
1908 DEFUN (ipv6_router_isis,
1909 ipv6_router_isis_cmd,
1910 "ipv6 router isis WORD",
1911 "IPv6 interface subcommands\n"
1912 "IPv6 Router interface commands\n"
1913 "IS-IS Routing for IPv6\n"
1914 "Routing process tag\n")
1915 {
1916 struct isis_circuit *c;
1917 struct interface *ifp;
1918 struct isis_area *area;
1919
1920 ifp = (struct interface *) vty->index;
1921 assert (ifp);
1922
1923 area = isis_area_lookup (argv[0]);
1924
1925 /* Prevent more than one circuit per interface */
1926 if (area)
1927 c = circuit_lookup_by_ifp (ifp, area->circuit_list);
1928 else
1929 c = NULL;
1930
1931 if (c && (ifp->info != NULL))
1932 {
1933 if (c->ipv6_router == 1)
1934 {
1935 vty_out (vty, "ISIS circuit is already defined for IPv6%s",
1936 VTY_NEWLINE);
1937 return CMD_WARNING;
1938 }
1939 }
1940
1941 /* this is here for ciscopability */
1942 if (!area)
1943 {
1944 vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
1945 return CMD_WARNING;
1946 }
1947
1948 if (!c)
1949 {
1950 c = circuit_lookup_by_ifp (ifp, isis->init_circ_list);
1951 c = isis_csm_state_change (ISIS_ENABLE, c, area);
1952 c->interface = ifp;
1953 ifp->info = c;
1954 }
1955
1956 if (!c)
1957 return CMD_WARNING;
1958
1959 c->ipv6_router = 1;
1960 area->ipv6_circuits++;
1961 circuit_update_nlpids (c);
1962
1963 vty->node = INTERFACE_NODE;
1964
1965 return CMD_SUCCESS;
1966 }
1967
1968 DEFUN (no_ipv6_router_isis,
1969 no_ipv6_router_isis_cmd,
1970 "no ipv6 router isis WORD",
1971 NO_STR
1972 "IPv6 interface subcommands\n"
1973 "IPv6 Router interface commands\n"
1974 "IS-IS Routing for IPv6\n"
1975 "Routing process tag\n")
1976 {
1977 struct isis_circuit *c;
1978 struct interface *ifp;
1979 struct isis_area *area;
1980
1981 ifp = (struct interface *) vty->index;
1982 /* UGLY - will remove l8r
1983 if (circuit == NULL) {
1984 return CMD_WARNING;
1985 } */
1986 assert (ifp);
1987
1988 area = isis_area_lookup (argv[0]);
1989 if (!area)
1990 {
1991 vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
1992 return CMD_WARNING;
1993 }
1994
1995 c = circuit_lookup_by_ifp (ifp, area->circuit_list);
1996 if (!c)
1997 return CMD_WARNING;
1998
1999 c->ipv6_router = 0;
2000 area->ipv6_circuits--;
2001 if (c->ip_router == 0)
2002 isis_csm_state_change (ISIS_DISABLE, c, area);
2003
2004 return CMD_SUCCESS;
2005 }
2006 #endif /* HAVE_IPV6 */
2007
2008 struct cmd_node interface_node = {
2009 INTERFACE_NODE,
2010 "%s(config-if)# ",
2011 1,
2012 };
2013
2014 int
2015 isis_if_new_hook (struct interface *ifp)
2016 {
2017 /* FIXME: Discuss if the circuit should be created here
2018 ifp->info = XMALLOC (MTYPE_ISIS_IF_INFO, sizeof (struct isis_if_info)); */
2019 ifp->info = NULL;
2020 return 0;
2021 }
2022
2023 int
2024 isis_if_delete_hook (struct interface *ifp)
2025 {
2026 /* FIXME: Discuss if the circuit should be created here
2027 XFREE (MTYPE_ISIS_IF_INFO, ifp->info);*/
2028 ifp->info = NULL;
2029 return 0;
2030 }
2031
2032 void
2033 isis_circuit_init ()
2034 {
2035 /* Initialize Zebra interface data structure */
2036 if_init ();
2037 if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
2038 if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
2039
2040 /* Install interface node */
2041 install_node (&interface_node, isis_interface_config_write);
2042 install_element (CONFIG_NODE, &interface_cmd);
2043
2044 install_default (INTERFACE_NODE);
2045 install_element (INTERFACE_NODE, &interface_desc_cmd);
2046 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2047
2048 install_element (INTERFACE_NODE, &ip_router_isis_cmd);
2049 install_element (INTERFACE_NODE, &no_ip_router_isis_cmd);
2050
2051 install_element (INTERFACE_NODE, &isis_circuit_type_cmd);
2052 install_element (INTERFACE_NODE, &no_isis_circuit_type_cmd);
2053
2054 install_element (INTERFACE_NODE, &isis_passwd_cmd);
2055 install_element (INTERFACE_NODE, &no_isis_passwd_cmd);
2056
2057 install_element (INTERFACE_NODE, &isis_priority_cmd);
2058 install_element (INTERFACE_NODE, &no_isis_priority_cmd);
2059 install_element (INTERFACE_NODE, &no_isis_priority_arg_cmd);
2060 install_element (INTERFACE_NODE, &isis_priority_l1_cmd);
2061 install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd);
2062 install_element (INTERFACE_NODE, &no_isis_priority_l1_arg_cmd);
2063 install_element (INTERFACE_NODE, &isis_priority_l2_cmd);
2064 install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd);
2065 install_element (INTERFACE_NODE, &no_isis_priority_l2_arg_cmd);
2066
2067 install_element (INTERFACE_NODE, &isis_metric_cmd);
2068 install_element (INTERFACE_NODE, &no_isis_metric_cmd);
2069 install_element (INTERFACE_NODE, &no_isis_metric_arg_cmd);
2070
2071 install_element (INTERFACE_NODE, &isis_hello_interval_cmd);
2072 install_element (INTERFACE_NODE, &no_isis_hello_interval_cmd);
2073 install_element (INTERFACE_NODE, &no_isis_hello_interval_arg_cmd);
2074 install_element (INTERFACE_NODE, &isis_hello_interval_l1_cmd);
2075 install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_cmd);
2076 install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_arg_cmd);
2077 install_element (INTERFACE_NODE, &isis_hello_interval_l2_cmd);
2078 install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_cmd);
2079 install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_arg_cmd);
2080
2081 install_element (INTERFACE_NODE, &isis_hello_multiplier_cmd);
2082 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
2083 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_arg_cmd);
2084 install_element (INTERFACE_NODE, &isis_hello_multiplier_l1_cmd);
2085 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd);
2086 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_arg_cmd);
2087 install_element (INTERFACE_NODE, &isis_hello_multiplier_l2_cmd);
2088 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd);
2089 install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_arg_cmd);
2090
2091 install_element (INTERFACE_NODE, &isis_hello_cmd);
2092 install_element (INTERFACE_NODE, &no_isis_hello_cmd);
2093 install_element (INTERFACE_NODE, &csnp_interval_cmd);
2094 install_element (INTERFACE_NODE, &no_csnp_interval_cmd);
2095 install_element (INTERFACE_NODE, &no_csnp_interval_arg_cmd);
2096 install_element (INTERFACE_NODE, &csnp_interval_l1_cmd);
2097 install_element (INTERFACE_NODE, &no_csnp_interval_l1_cmd);
2098 install_element (INTERFACE_NODE, &no_csnp_interval_l1_arg_cmd);
2099 install_element (INTERFACE_NODE, &csnp_interval_l2_cmd);
2100 install_element (INTERFACE_NODE, &no_csnp_interval_l2_cmd);
2101 install_element (INTERFACE_NODE, &no_csnp_interval_l2_arg_cmd);
2102
2103 #ifdef HAVE_IPV6
2104 install_element (INTERFACE_NODE, &ipv6_router_isis_cmd);
2105 install_element (INTERFACE_NODE, &no_ipv6_router_isis_cmd);
2106 #endif
2107 }