blob: 85e4f9c76bcf18529337db819b3e2dbd5df8350d [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
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 */
jardineb5d44e2003-12-23 08:09:43 +000022#include <zebra.h>
hasso37da8c02004-05-19 11:38:40 +000023#ifdef GNU_LINUX
jardineb5d44e2003-12-23 08:09:43 +000024#include <net/ethernet.h>
hasso37da8c02004-05-19 11:38:40 +000025#else
26#include <netinet/if_ether.h>
27#endif
jardineb5d44e2003-12-23 08:09:43 +000028
Paul Jakma238497f2007-08-07 18:49:18 +000029#ifndef ETHER_ADDR_LEN
30#define ETHER_ADDR_LEN ETHERADDRL
31#endif
32
jardineb5d44e2003-12-23 08:09:43 +000033#include "log.h"
34#include "memory.h"
35#include "if.h"
36#include "linklist.h"
37#include "command.h"
38#include "thread.h"
Olivier Dugeon4f593572016-04-19 19:03:05 +020039#include "vty.h"
jardineb5d44e2003-12-23 08:09:43 +000040#include "hash.h"
41#include "prefix.h"
42#include "stream.h"
43
44#include "isisd/dict.h"
45#include "isisd/include-netbsd/iso.h"
46#include "isisd/isis_constants.h"
47#include "isisd/isis_common.h"
Josh Bailey3f045a02012-03-24 08:35:20 -070048#include "isisd/isis_flags.h"
jardineb5d44e2003-12-23 08:09:43 +000049#include "isisd/isis_circuit.h"
50#include "isisd/isis_tlv.h"
51#include "isisd/isis_lsp.h"
52#include "isisd/isis_pdu.h"
53#include "isisd/isis_network.h"
54#include "isisd/isis_misc.h"
55#include "isisd/isis_constants.h"
56#include "isisd/isis_adjacency.h"
57#include "isisd/isis_dr.h"
jardineb5d44e2003-12-23 08:09:43 +000058#include "isisd/isisd.h"
59#include "isisd/isis_csm.h"
60#include "isisd/isis_events.h"
Olivier Dugeon4f593572016-04-19 19:03:05 +020061#include "isisd/isis_te.h"
jardineb5d44e2003-12-23 08:09:43 +000062
Paul Jakma41b36e92006-12-08 01:09:50 +000063/*
64 * Prototypes.
65 */
Paul Jakma41b36e92006-12-08 01:09:50 +000066int isis_interface_config_write(struct vty *);
67int isis_if_new_hook(struct interface *);
68int isis_if_delete_hook(struct interface *);
69
jardineb5d44e2003-12-23 08:09:43 +000070struct isis_circuit *
71isis_circuit_new ()
72{
73 struct isis_circuit *circuit;
74 int i;
75
hasso3fdb2dd2005-09-28 18:45:54 +000076 circuit = XCALLOC (MTYPE_ISIS_CIRCUIT, sizeof (struct isis_circuit));
Josh Bailey3f045a02012-03-24 08:35:20 -070077 if (circuit == NULL)
hassof390d2c2004-09-10 20:48:21 +000078 {
79 zlog_err ("Can't malloc isis circuit");
80 return NULL;
81 }
82
Josh Bailey3f045a02012-03-24 08:35:20 -070083 /*
84 * Default values
85 */
86 circuit->is_type = IS_LEVEL_1_AND_2;
87 circuit->flags = 0;
88 circuit->pad_hellos = 1;
89 for (i = 0; i < 2; i++)
90 {
91 circuit->hello_interval[i] = DEFAULT_HELLO_INTERVAL;
92 circuit->hello_multiplier[i] = DEFAULT_HELLO_MULTIPLIER;
93 circuit->csnp_interval[i] = DEFAULT_CSNP_INTERVAL;
94 circuit->psnp_interval[i] = DEFAULT_PSNP_INTERVAL;
95 circuit->priority[i] = DEFAULT_PRIORITY;
96 circuit->metrics[i].metric_default = DEFAULT_CIRCUIT_METRIC;
97 circuit->metrics[i].metric_expense = METRICS_UNSUPPORTED;
98 circuit->metrics[i].metric_error = METRICS_UNSUPPORTED;
99 circuit->metrics[i].metric_delay = METRICS_UNSUPPORTED;
100 circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC;
101 }
102
Olivier Dugeon4f593572016-04-19 19:03:05 +0200103 circuit->mtc = mpls_te_circuit_new();
104
jardineb5d44e2003-12-23 08:09:43 +0000105 return circuit;
106}
107
jardineb5d44e2003-12-23 08:09:43 +0000108void
Josh Bailey3f045a02012-03-24 08:35:20 -0700109isis_circuit_del (struct isis_circuit *circuit)
110{
111 if (!circuit)
112 return;
113
114 isis_circuit_if_unbind (circuit, circuit->interface);
115
116 /* and lastly the circuit itself */
117 XFREE (MTYPE_ISIS_CIRCUIT, circuit);
118
119 return;
120}
121
122void
jardineb5d44e2003-12-23 08:09:43 +0000123isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area)
124{
Josh Bailey3f045a02012-03-24 08:35:20 -0700125 assert (area);
jardineb5d44e2003-12-23 08:09:43 +0000126 circuit->area = area;
Josh Bailey3f045a02012-03-24 08:35:20 -0700127
jardineb5d44e2003-12-23 08:09:43 +0000128 /*
Christian Franke7324ae12015-11-10 18:04:48 +0100129 * Whenever the is-type of an area is changed, the is-type of each circuit
130 * in that area is updated to a non-empty subset of the area is-type.
131 * Inversely, when configuring a new circuit, this property should be
132 * ensured as well.
jardineb5d44e2003-12-23 08:09:43 +0000133 */
Christian Franke7324ae12015-11-10 18:04:48 +0100134 if (area->is_type != IS_LEVEL_1_AND_2)
135 circuit->is_type = area->is_type;
jardineb5d44e2003-12-23 08:09:43 +0000136
137 /*
138 * Add the circuit into area
139 */
140 listnode_add (area->circuit_list, circuit);
141
142 circuit->idx = flags_get_index (&area->flags);
jardineb5d44e2003-12-23 08:09:43 +0000143
144 return;
145}
146
hassof390d2c2004-09-10 20:48:21 +0000147void
Josh Bailey3f045a02012-03-24 08:35:20 -0700148isis_circuit_deconfigure (struct isis_circuit *circuit, struct isis_area *area)
jardineb5d44e2003-12-23 08:09:43 +0000149{
jardineb5d44e2003-12-23 08:09:43 +0000150 /* Free the index of SRM and SSN flags */
151 flags_free_index (&area->flags, circuit->idx);
Josh Bailey3f045a02012-03-24 08:35:20 -0700152 circuit->idx = 0;
153 /* Remove circuit from area */
154 assert (circuit->area == area);
155 listnode_delete (area->circuit_list, circuit);
156 circuit->area = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000157
158 return;
159}
160
161struct isis_circuit *
162circuit_lookup_by_ifp (struct interface *ifp, struct list *list)
163{
164 struct isis_circuit *circuit = NULL;
165 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000166
jardineb5d44e2003-12-23 08:09:43 +0000167 if (!list)
168 return NULL;
hassof390d2c2004-09-10 20:48:21 +0000169
paul1eb8ef22005-04-07 07:30:20 +0000170 for (ALL_LIST_ELEMENTS_RO (list, node, circuit))
171 if (circuit->interface == ifp)
Josh Bailey3f045a02012-03-24 08:35:20 -0700172 {
173 assert (ifp->info == circuit);
174 return circuit;
175 }
176
jardineb5d44e2003-12-23 08:09:43 +0000177 return NULL;
178}
179
180struct isis_circuit *
181circuit_scan_by_ifp (struct interface *ifp)
182{
183 struct isis_area *area;
184 struct listnode *node;
185 struct isis_circuit *circuit;
186
Josh Bailey3f045a02012-03-24 08:35:20 -0700187 if (ifp->info)
188 return (struct isis_circuit *)ifp->info;
jardineb5d44e2003-12-23 08:09:43 +0000189
Josh Bailey3f045a02012-03-24 08:35:20 -0700190 if (isis->area_list)
hassof390d2c2004-09-10 20:48:21 +0000191 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700192 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
193 {
194 circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
195 if (circuit)
196 return circuit;
197 }
hassof390d2c2004-09-10 20:48:21 +0000198 }
jardineb5d44e2003-12-23 08:09:43 +0000199 return circuit_lookup_by_ifp (ifp, isis->init_circ_list);
200}
201
Olivier Dugeon4f593572016-04-19 19:03:05 +0200202struct isis_circuit * isis_circuit_lookup (struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000203{
Josh Bailey3f045a02012-03-24 08:35:20 -0700204 struct interface *ifp;
205 struct isis_circuit *circuit;
jardineb5d44e2003-12-23 08:09:43 +0000206
Josh Bailey3f045a02012-03-24 08:35:20 -0700207 ifp = (struct interface *) vty->index;
208 if (!ifp)
hassof390d2c2004-09-10 20:48:21 +0000209 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700210 vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
211 return NULL;
hassof390d2c2004-09-10 20:48:21 +0000212 }
hassof390d2c2004-09-10 20:48:21 +0000213
Josh Bailey3f045a02012-03-24 08:35:20 -0700214 circuit = circuit_scan_by_ifp (ifp);
215 if (!circuit)
216 {
217 vty_out (vty, "ISIS is not enabled on circuit %s%s",
218 ifp->name, VTY_NEWLINE);
219 return NULL;
220 }
jardineb5d44e2003-12-23 08:09:43 +0000221
Josh Bailey3f045a02012-03-24 08:35:20 -0700222 return circuit;
jardineb5d44e2003-12-23 08:09:43 +0000223}
224
225void
hassof891f442004-09-14 13:54:30 +0000226isis_circuit_add_addr (struct isis_circuit *circuit,
227 struct connected *connected)
jardineb5d44e2003-12-23 08:09:43 +0000228{
Josh Bailey3f045a02012-03-24 08:35:20 -0700229 struct listnode *node;
jardineb5d44e2003-12-23 08:09:43 +0000230 struct prefix_ipv4 *ipv4;
hassof390d2c2004-09-10 20:48:21 +0000231 u_char buf[BUFSIZ];
jardineb5d44e2003-12-23 08:09:43 +0000232#ifdef HAVE_IPV6
233 struct prefix_ipv6 *ipv6;
234#endif /* HAVE_IPV6 */
hassof891f442004-09-14 13:54:30 +0000235
jardineb5d44e2003-12-23 08:09:43 +0000236 memset (&buf, 0, BUFSIZ);
hassof891f442004-09-14 13:54:30 +0000237 if (connected->address->family == AF_INET)
hassof390d2c2004-09-10 20:48:21 +0000238 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700239 u_int32_t addr = connected->address->u.prefix4.s_addr;
240 addr = ntohl (addr);
241 if (IPV4_NET0(addr) ||
242 IPV4_NET127(addr) ||
243 IN_CLASSD(addr) ||
244 IPV4_LINKLOCAL(addr))
245 return;
246
247 for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4))
248 if (prefix_same ((struct prefix *) ipv4, connected->address))
249 return;
250
hassof390d2c2004-09-10 20:48:21 +0000251 ipv4 = prefix_ipv4_new ();
hassof891f442004-09-14 13:54:30 +0000252 ipv4->prefixlen = connected->address->prefixlen;
253 ipv4->prefix = connected->address->u.prefix4;
hassof390d2c2004-09-10 20:48:21 +0000254 listnode_add (circuit->ip_addrs, ipv4);
Olivier Dugeon4f593572016-04-19 19:03:05 +0200255
256 /* Update MPLS TE Local IP address parameter */
257 set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix);
258
hasso0dae85e2004-09-26 19:53:47 +0000259 if (circuit->area)
Josh Bailey3f045a02012-03-24 08:35:20 -0700260 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
hassof891f442004-09-14 13:54:30 +0000261
jardineb5d44e2003-12-23 08:09:43 +0000262#ifdef EXTREME_DEBUG
hassof891f442004-09-14 13:54:30 +0000263 prefix2str (connected->address, buf, BUFSIZ);
hasso529d65b2004-12-24 00:14:50 +0000264 zlog_debug ("Added IP address %s to circuit %d", buf,
hassof390d2c2004-09-10 20:48:21 +0000265 circuit->circuit_id);
266#endif /* EXTREME_DEBUG */
jardineb5d44e2003-12-23 08:09:43 +0000267 }
hassof390d2c2004-09-10 20:48:21 +0000268#ifdef HAVE_IPV6
hassof891f442004-09-14 13:54:30 +0000269 if (connected->address->family == AF_INET6)
hassof390d2c2004-09-10 20:48:21 +0000270 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700271 if (IN6_IS_ADDR_LOOPBACK(&connected->address->u.prefix6))
272 return;
273
274 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ipv6))
275 if (prefix_same ((struct prefix *) ipv6, connected->address))
276 return;
277 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ipv6))
278 if (prefix_same ((struct prefix *) ipv6, connected->address))
279 return;
280
hassof390d2c2004-09-10 20:48:21 +0000281 ipv6 = prefix_ipv6_new ();
hassof891f442004-09-14 13:54:30 +0000282 ipv6->prefixlen = connected->address->prefixlen;
283 ipv6->prefix = connected->address->u.prefix6;
284
hassof390d2c2004-09-10 20:48:21 +0000285 if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
hassof891f442004-09-14 13:54:30 +0000286 listnode_add (circuit->ipv6_link, ipv6);
hassof390d2c2004-09-10 20:48:21 +0000287 else
hassof891f442004-09-14 13:54:30 +0000288 listnode_add (circuit->ipv6_non_link, ipv6);
hasso0dae85e2004-09-26 19:53:47 +0000289 if (circuit->area)
Josh Bailey3f045a02012-03-24 08:35:20 -0700290 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
hassof891f442004-09-14 13:54:30 +0000291
jardineb5d44e2003-12-23 08:09:43 +0000292#ifdef EXTREME_DEBUG
hassof891f442004-09-14 13:54:30 +0000293 prefix2str (connected->address, buf, BUFSIZ);
hasso529d65b2004-12-24 00:14:50 +0000294 zlog_debug ("Added IPv6 address %s to circuit %d", buf,
hassof390d2c2004-09-10 20:48:21 +0000295 circuit->circuit_id);
296#endif /* EXTREME_DEBUG */
297 }
jardineb5d44e2003-12-23 08:09:43 +0000298#endif /* HAVE_IPV6 */
jardineb5d44e2003-12-23 08:09:43 +0000299 return;
300}
301
302void
303isis_circuit_del_addr (struct isis_circuit *circuit,
hassof390d2c2004-09-10 20:48:21 +0000304 struct connected *connected)
jardineb5d44e2003-12-23 08:09:43 +0000305{
hassof891f442004-09-14 13:54:30 +0000306 struct prefix_ipv4 *ipv4, *ip = NULL;
307 struct listnode *node;
hassof891f442004-09-14 13:54:30 +0000308 u_char buf[BUFSIZ];
309#ifdef HAVE_IPV6
310 struct prefix_ipv6 *ipv6, *ip6 = NULL;
Paul Jakma41b36e92006-12-08 01:09:50 +0000311 int found = 0;
hassof891f442004-09-14 13:54:30 +0000312#endif /* HAVE_IPV6 */
jardineb5d44e2003-12-23 08:09:43 +0000313
hassof891f442004-09-14 13:54:30 +0000314 memset (&buf, 0, BUFSIZ);
315 if (connected->address->family == AF_INET)
316 {
317 ipv4 = prefix_ipv4_new ();
318 ipv4->prefixlen = connected->address->prefixlen;
319 ipv4->prefix = connected->address->u.prefix4;
320
paul1eb8ef22005-04-07 07:30:20 +0000321 for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip))
Josh Bailey3f045a02012-03-24 08:35:20 -0700322 if (prefix_same ((struct prefix *) ip, (struct prefix *) ipv4))
paul1eb8ef22005-04-07 07:30:20 +0000323 break;
hassof891f442004-09-14 13:54:30 +0000324
325 if (ip)
326 {
327 listnode_delete (circuit->ip_addrs, ip);
Josh Bailey3f045a02012-03-24 08:35:20 -0700328 if (circuit->area)
329 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
hassof891f442004-09-14 13:54:30 +0000330 }
331 else
332 {
hassof7c43dc2004-09-26 16:24:14 +0000333 prefix2str (connected->address, (char *)buf, BUFSIZ);
Josh Bailey3f045a02012-03-24 08:35:20 -0700334 zlog_warn ("Nonexitant ip address %s removal attempt from \
335 circuit %d", buf, circuit->circuit_id);
Christian Frankeec874162015-11-10 18:33:12 +0100336 zlog_warn ("Current ip addresses on %s:", circuit->interface->name);
337 for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ip))
338 {
339 prefix2str((struct prefix*)ip, (char *)buf, BUFSIZ);
340 zlog_warn(" %s", buf);
341 }
342 zlog_warn("End of addresses");
hassof891f442004-09-14 13:54:30 +0000343 }
David Lampartere8aca322012-11-27 01:10:30 +0000344
345 prefix_ipv4_free (ipv4);
hassof891f442004-09-14 13:54:30 +0000346 }
347#ifdef HAVE_IPV6
348 if (connected->address->family == AF_INET6)
349 {
350 ipv6 = prefix_ipv6_new ();
351 ipv6->prefixlen = connected->address->prefixlen;
352 ipv6->prefix = connected->address->u.prefix6;
353
354 if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
355 {
paul1eb8ef22005-04-07 07:30:20 +0000356 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_link, node, ip6))
hassof891f442004-09-14 13:54:30 +0000357 {
hassof891f442004-09-14 13:54:30 +0000358 if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
359 break;
360 }
361 if (ip6)
362 {
363 listnode_delete (circuit->ipv6_link, ip6);
364 found = 1;
365 }
366 }
367 else
368 {
paul1eb8ef22005-04-07 07:30:20 +0000369 for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, node, ip6))
hassof891f442004-09-14 13:54:30 +0000370 {
hassof891f442004-09-14 13:54:30 +0000371 if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
372 break;
373 }
374 if (ip6)
375 {
376 listnode_delete (circuit->ipv6_non_link, ip6);
377 found = 1;
378 }
379 }
380
381 if (!found)
382 {
hassof7c43dc2004-09-26 16:24:14 +0000383 prefix2str (connected->address, (char *)buf, BUFSIZ);
Josh Bailey3f045a02012-03-24 08:35:20 -0700384 zlog_warn ("Nonexitant ip address %s removal attempt from \
385 circuit %d", buf, circuit->circuit_id);
Christian Frankeec874162015-11-10 18:33:12 +0100386 zlog_warn ("Current ip addresses on %s:", circuit->interface->name);
387 for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ip6))
388 {
389 prefix2str((struct prefix*)ip6, (char *)buf, BUFSIZ);
390 zlog_warn(" %s", buf);
391 }
392 zlog_warn(" -----");
393 for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip6))
394 {
395 prefix2str((struct prefix*)ip6, (char *)buf, BUFSIZ);
396 zlog_warn(" %s", buf);
397 }
398 zlog_warn("End of addresses");
hassof891f442004-09-14 13:54:30 +0000399 }
Josh Bailey3f045a02012-03-24 08:35:20 -0700400 else if (circuit->area)
401 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
David Lampartere8aca322012-11-27 01:10:30 +0000402
403 prefix_ipv6_free (ipv6);
hassof891f442004-09-14 13:54:30 +0000404 }
405#endif /* HAVE_IPV6 */
406 return;
jardineb5d44e2003-12-23 08:09:43 +0000407}
408
Josh Bailey3f045a02012-03-24 08:35:20 -0700409static u_char
410isis_circuit_id_gen (struct interface *ifp)
411{
412 u_char id = 0;
413 char ifname[16];
414 unsigned int i;
415 int start = -1, end = -1;
416
417 /*
418 * Get a stable circuit id from ifname. This makes
419 * the ifindex from flapping when netdevs are created
420 * and deleted on the fly. Note that this circuit id
421 * is used in pseudo lsps so it is better to be stable.
422 * The following code works on any reasonanle ifname
423 * like: eth1 or trk-1.1 etc.
424 */
425 for (i = 0; i < strlen (ifp->name); i++)
426 {
David Lamparter52f02b42015-04-10 09:14:30 +0200427 if (isdigit((unsigned char)ifp->name[i]))
Josh Bailey3f045a02012-03-24 08:35:20 -0700428 {
429 if (start < 0)
430 {
431 start = i;
432 end = i + 1;
433 }
434 else
435 {
436 end = i + 1;
437 }
438 }
439 else if (start >= 0)
440 break;
441 }
442
443 if ((start >= 0) && (end >= start) && (end - start) < 16)
444 {
445 memset (ifname, 0, 16);
446 strncpy (ifname, &ifp->name[start], end - start);
447 id = (u_char)atoi(ifname);
448 }
449
450 /* Try to be unique. */
451 if (!id)
452 id = (u_char)((ifp->ifindex & 0xff) | 0x80);
453
454 return id;
455}
456
jardineb5d44e2003-12-23 08:09:43 +0000457void
458isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
459{
paul1eb8ef22005-04-07 07:30:20 +0000460 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000461 struct connected *conn;
462
Josh Bailey3f045a02012-03-24 08:35:20 -0700463 circuit->circuit_id = isis_circuit_id_gen (ifp);
hassof390d2c2004-09-10 20:48:21 +0000464
Josh Bailey3f045a02012-03-24 08:35:20 -0700465 isis_circuit_if_bind (circuit, ifp);
jardineb5d44e2003-12-23 08:09:43 +0000466 /* isis_circuit_update_addrs (circuit, ifp); */
467
hassof390d2c2004-09-10 20:48:21 +0000468 if (if_is_broadcast (ifp))
469 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700470 if (circuit->circ_type_config == CIRCUIT_T_P2P)
471 circuit->circ_type = CIRCUIT_T_P2P;
hassof390d2c2004-09-10 20:48:21 +0000472 else
Josh Bailey3f045a02012-03-24 08:35:20 -0700473 circuit->circ_type = CIRCUIT_T_BROADCAST;
hassof390d2c2004-09-10 20:48:21 +0000474 }
475 else if (if_is_pointopoint (ifp))
476 {
477 circuit->circ_type = CIRCUIT_T_P2P;
478 }
Josh Bailey3f045a02012-03-24 08:35:20 -0700479 else if (if_is_loopback (ifp))
480 {
481 circuit->circ_type = CIRCUIT_T_LOOPBACK;
482 circuit->is_passive = 1;
483 }
hassof390d2c2004-09-10 20:48:21 +0000484 else
485 {
hassoc89c05d2005-09-04 21:36:36 +0000486 /* It's normal in case of loopback etc. */
487 if (isis->debugs & DEBUG_EVENTS)
Josh Bailey3f045a02012-03-24 08:35:20 -0700488 zlog_debug ("isis_circuit_if_add: unsupported media");
489 circuit->circ_type = CIRCUIT_T_UNKNOWN;
hassof390d2c2004-09-10 20:48:21 +0000490 }
491
Josh Bailey3f045a02012-03-24 08:35:20 -0700492 circuit->ip_addrs = list_new ();
493#ifdef HAVE_IPV6
494 circuit->ipv6_link = list_new ();
495 circuit->ipv6_non_link = list_new ();
496#endif /* HAVE_IPV6 */
497
paul1eb8ef22005-04-07 07:30:20 +0000498 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
499 isis_circuit_add_addr (circuit, conn);
jardineb5d44e2003-12-23 08:09:43 +0000500
501 return;
502}
503
504void
Josh Bailey3f045a02012-03-24 08:35:20 -0700505isis_circuit_if_del (struct isis_circuit *circuit, struct interface *ifp)
jardineb5d44e2003-12-23 08:09:43 +0000506{
Josh Bailey3f045a02012-03-24 08:35:20 -0700507 struct listnode *node, *nnode;
508 struct connected *conn;
hassof390d2c2004-09-10 20:48:21 +0000509
Josh Bailey3f045a02012-03-24 08:35:20 -0700510 assert (circuit->interface == ifp);
511
512 /* destroy addresses */
513 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
514 isis_circuit_del_addr (circuit, conn);
515
516 if (circuit->ip_addrs)
hassof390d2c2004-09-10 20:48:21 +0000517 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700518 assert (listcount(circuit->ip_addrs) == 0);
519 list_delete (circuit->ip_addrs);
520 circuit->ip_addrs = NULL;
hassof390d2c2004-09-10 20:48:21 +0000521 }
jardineb5d44e2003-12-23 08:09:43 +0000522
Josh Bailey3f045a02012-03-24 08:35:20 -0700523#ifdef HAVE_IPV6
524 if (circuit->ipv6_link)
hassof390d2c2004-09-10 20:48:21 +0000525 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700526 assert (listcount(circuit->ipv6_link) == 0);
527 list_delete (circuit->ipv6_link);
528 circuit->ipv6_link = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000529 }
jardineb5d44e2003-12-23 08:09:43 +0000530
Josh Bailey3f045a02012-03-24 08:35:20 -0700531 if (circuit->ipv6_non_link)
hassof390d2c2004-09-10 20:48:21 +0000532 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700533 assert (listcount(circuit->ipv6_non_link) == 0);
534 list_delete (circuit->ipv6_non_link);
535 circuit->ipv6_non_link = NULL;
hassof390d2c2004-09-10 20:48:21 +0000536 }
Josh Bailey3f045a02012-03-24 08:35:20 -0700537#endif /* HAVE_IPV6 */
538
539 circuit->circ_type = CIRCUIT_T_UNKNOWN;
540 circuit->circuit_id = 0;
jardineb5d44e2003-12-23 08:09:43 +0000541
jardineb5d44e2003-12-23 08:09:43 +0000542 return;
543}
544
545void
Josh Bailey3f045a02012-03-24 08:35:20 -0700546isis_circuit_if_bind (struct isis_circuit *circuit, struct interface *ifp)
jardineb5d44e2003-12-23 08:09:43 +0000547{
Josh Bailey3f045a02012-03-24 08:35:20 -0700548 assert (circuit != NULL);
549 assert (ifp != NULL);
550 if (circuit->interface)
551 assert (circuit->interface == ifp);
552 else
553 circuit->interface = ifp;
554 if (ifp->info)
555 assert (ifp->info == circuit);
556 else
557 ifp->info = circuit;
Olivier Dugeon4f593572016-04-19 19:03:05 +0200558 isis_link_params_update (circuit, ifp);
Josh Bailey3f045a02012-03-24 08:35:20 -0700559}
560
561void
562isis_circuit_if_unbind (struct isis_circuit *circuit, struct interface *ifp)
563{
564 assert (circuit != NULL);
565 assert (ifp != NULL);
566 assert (circuit->interface == ifp);
567 assert (ifp->info == circuit);
jardineb5d44e2003-12-23 08:09:43 +0000568 circuit->interface = NULL;
Josh Bailey3f045a02012-03-24 08:35:20 -0700569 ifp->info = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000570}
571
Josh Bailey3f045a02012-03-24 08:35:20 -0700572static void
573isis_circuit_update_all_srmflags (struct isis_circuit *circuit, int is_set)
574{
575 struct isis_area *area;
576 struct isis_lsp *lsp;
577 dnode_t *dnode, *dnode_next;
578 int level;
579
580 assert (circuit);
581 area = circuit->area;
582 assert (area);
583 for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++)
584 {
585 if (level & circuit->is_type)
586 {
587 if (area->lspdb[level - 1] &&
588 dict_count (area->lspdb[level - 1]) > 0)
589 {
590 for (dnode = dict_first (area->lspdb[level - 1]);
591 dnode != NULL; dnode = dnode_next)
592 {
593 dnode_next = dict_next (area->lspdb[level - 1], dnode);
594 lsp = dnode_get (dnode);
595 if (is_set)
596 {
597 ISIS_SET_FLAG (lsp->SRMflags, circuit);
598 }
599 else
600 {
601 ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
602 }
603 }
604 }
605 }
606 }
607}
608
Christian Frankef1fc1db2015-11-10 18:43:31 +0100609size_t
610isis_circuit_pdu_size(struct isis_circuit *circuit)
611{
612 return ISO_MTU(circuit);
613}
614
615void
616isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream)
617{
618 size_t stream_size = isis_circuit_pdu_size(circuit);
619
620 if (!*stream)
621 {
622 *stream = stream_new(stream_size);
623 }
624 else
625 {
626 if (STREAM_SIZE(*stream) != stream_size)
627 stream_resize(*stream, stream_size);
628 stream_reset(*stream);
629 }
630}
631
Josh Bailey3f045a02012-03-24 08:35:20 -0700632int
jardineb5d44e2003-12-23 08:09:43 +0000633isis_circuit_up (struct isis_circuit *circuit)
634{
Josh Bailey3f045a02012-03-24 08:35:20 -0700635 int retv;
636
637 /* Set the flags for all the lsps of the circuit. */
638 isis_circuit_update_all_srmflags (circuit, 1);
639
640 if (circuit->state == C_STATE_UP)
641 return ISIS_OK;
642
643 if (circuit->is_passive)
644 return ISIS_OK;
jardineb5d44e2003-12-23 08:09:43 +0000645
Christian Frankef1fc1db2015-11-10 18:43:31 +0100646 if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit))
647 {
648 zlog_err("Interface MTU %zu on %s is too low to support area lsp mtu %u!",
649 isis_circuit_pdu_size(circuit), circuit->interface->name,
650 circuit->area->lsp_mtu);
Christian Franke8ed8d0b2016-04-03 12:46:26 -0300651 isis_circuit_update_all_srmflags(circuit, 0);
Christian Frankef1fc1db2015-11-10 18:43:31 +0100652 return ISIS_ERROR;
653 }
654
hassof390d2c2004-09-10 20:48:21 +0000655 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
656 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700657 /*
658 * Get the Hardware Address
659 */
Josh Bailey3f045a02012-03-24 08:35:20 -0700660 if (circuit->interface->hw_addr_len != ETH_ALEN)
661 {
662 zlog_warn ("unsupported link layer");
663 }
664 else
665 {
666 memcpy (circuit->u.bc.snpa, circuit->interface->hw_addr, ETH_ALEN);
667 }
668#ifdef EXTREME_DEGUG
669 zlog_debug ("isis_circuit_if_add: if_id %d, isomtu %d snpa %s",
670 circuit->interface->ifindex, ISO_MTU (circuit),
671 snpa_print (circuit->u.bc.snpa));
672#endif /* EXTREME_DEBUG */
Josh Bailey3f045a02012-03-24 08:35:20 -0700673
674 circuit->u.bc.adjdb[0] = list_new ();
675 circuit->u.bc.adjdb[1] = list_new ();
676
hassof390d2c2004-09-10 20:48:21 +0000677 /*
678 * ISO 10589 - 8.4.1 Enabling of broadcast circuits
679 */
jardineb5d44e2003-12-23 08:09:43 +0000680
hassof390d2c2004-09-10 20:48:21 +0000681 /* initilizing the hello sending threads
682 * for a broadcast IF
683 */
jardineb5d44e2003-12-23 08:09:43 +0000684
hassof390d2c2004-09-10 20:48:21 +0000685 /* 8.4.1 a) commence sending of IIH PDUs */
686
Josh Bailey3f045a02012-03-24 08:35:20 -0700687 if (circuit->is_type & IS_LEVEL_1)
688 {
689 thread_add_event (master, send_lan_l1_hello, circuit, 0);
690 circuit->u.bc.lan_neighs[0] = list_new ();
691 }
hassof390d2c2004-09-10 20:48:21 +0000692
Josh Bailey3f045a02012-03-24 08:35:20 -0700693 if (circuit->is_type & IS_LEVEL_2)
694 {
695 thread_add_event (master, send_lan_l2_hello, circuit, 0);
696 circuit->u.bc.lan_neighs[1] = list_new ();
697 }
hassof390d2c2004-09-10 20:48:21 +0000698
699 /* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
700 /* 8.4.1 c) FIXME: listen for ESH PDUs */
701
702 /* 8.4.1 d) */
703 /* dr election will commence in... */
Josh Bailey3f045a02012-03-24 08:35:20 -0700704 if (circuit->is_type & IS_LEVEL_1)
705 THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
706 circuit, 2 * circuit->hello_interval[0]);
707 if (circuit->is_type & IS_LEVEL_2)
708 THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
709 circuit, 2 * circuit->hello_interval[1]);
jardineb5d44e2003-12-23 08:09:43 +0000710 }
hassof390d2c2004-09-10 20:48:21 +0000711 else
712 {
713 /* initializing the hello send threads
714 * for a ptp IF
715 */
Josh Bailey3f045a02012-03-24 08:35:20 -0700716 circuit->u.p2p.neighbor = NULL;
hassof390d2c2004-09-10 20:48:21 +0000717 thread_add_event (master, send_p2p_hello, circuit, 0);
jardineb5d44e2003-12-23 08:09:43 +0000718 }
719
jardineb5d44e2003-12-23 08:09:43 +0000720 /* initializing PSNP timers */
Josh Bailey3f045a02012-03-24 08:35:20 -0700721 if (circuit->is_type & IS_LEVEL_1)
722 THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
723 isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
724
725 if (circuit->is_type & IS_LEVEL_2)
726 THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
727 isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
728
729 /* unified init for circuits; ignore warnings below this level */
730 retv = isis_sock_init (circuit);
731 if (retv != ISIS_OK)
hassof390d2c2004-09-10 20:48:21 +0000732 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700733 isis_circuit_down (circuit);
734 return retv;
hassof390d2c2004-09-10 20:48:21 +0000735 }
736
Josh Bailey3f045a02012-03-24 08:35:20 -0700737 /* initialize the circuit streams after opening connection */
Christian Frankef1fc1db2015-11-10 18:43:31 +0100738 isis_circuit_stream(circuit, &circuit->rcv_stream);
739 isis_circuit_stream(circuit, &circuit->snd_stream);
jardineb5d44e2003-12-23 08:09:43 +0000740
jardineb5d44e2003-12-23 08:09:43 +0000741#ifdef GNU_LINUX
hassof390d2c2004-09-10 20:48:21 +0000742 THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
Josh Bailey3f045a02012-03-24 08:35:20 -0700743 circuit->fd);
jardineb5d44e2003-12-23 08:09:43 +0000744#else
hassof390d2c2004-09-10 20:48:21 +0000745 THREAD_TIMER_ON (master, circuit->t_read, isis_receive, circuit,
Josh Bailey3f045a02012-03-24 08:35:20 -0700746 circuit->fd);
jardineb5d44e2003-12-23 08:09:43 +0000747#endif
Josh Bailey3f045a02012-03-24 08:35:20 -0700748
749 circuit->lsp_queue = list_new ();
750 circuit->lsp_queue_last_cleared = time (NULL);
751
752 return ISIS_OK;
jardineb5d44e2003-12-23 08:09:43 +0000753}
754
755void
756isis_circuit_down (struct isis_circuit *circuit)
757{
Josh Bailey3f045a02012-03-24 08:35:20 -0700758 if (circuit->state != C_STATE_UP)
759 return;
760
761 /* Clear the flags for all the lsps of the circuit. */
762 isis_circuit_update_all_srmflags (circuit, 0);
763
hassof390d2c2004-09-10 20:48:21 +0000764 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
765 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700766 /* destroy neighbour lists */
767 if (circuit->u.bc.lan_neighs[0])
768 {
769 list_delete (circuit->u.bc.lan_neighs[0]);
770 circuit->u.bc.lan_neighs[0] = NULL;
771 }
772 if (circuit->u.bc.lan_neighs[1])
773 {
774 list_delete (circuit->u.bc.lan_neighs[1]);
775 circuit->u.bc.lan_neighs[1] = NULL;
776 }
777 /* destroy adjacency databases */
778 if (circuit->u.bc.adjdb[0])
779 {
780 circuit->u.bc.adjdb[0]->del = isis_delete_adj;
781 list_delete (circuit->u.bc.adjdb[0]);
782 circuit->u.bc.adjdb[0] = NULL;
783 }
784 if (circuit->u.bc.adjdb[1])
785 {
786 circuit->u.bc.adjdb[1]->del = isis_delete_adj;
787 list_delete (circuit->u.bc.adjdb[1]);
788 circuit->u.bc.adjdb[1] = NULL;
789 }
790 if (circuit->u.bc.is_dr[0])
791 {
792 isis_dr_resign (circuit, 1);
793 circuit->u.bc.is_dr[0] = 0;
794 }
795 memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
796 if (circuit->u.bc.is_dr[1])
797 {
798 isis_dr_resign (circuit, 2);
799 circuit->u.bc.is_dr[1] = 0;
800 }
801 memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
802 memset (circuit->u.bc.snpa, 0, ETH_ALEN);
803
hassof390d2c2004-09-10 20:48:21 +0000804 THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]);
805 THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]);
hassof891f442004-09-14 13:54:30 +0000806 THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
807 THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
Josh Bailey3f045a02012-03-24 08:35:20 -0700808 THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[0]);
809 THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[1]);
Christian Franke61010c32015-11-10 18:43:34 +0100810 circuit->lsp_regenerate_pending[0] = 0;
811 circuit->lsp_regenerate_pending[1] = 0;
hassof390d2c2004-09-10 20:48:21 +0000812 }
813 else if (circuit->circ_type == CIRCUIT_T_P2P)
814 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700815 isis_delete_adj (circuit->u.p2p.neighbor);
816 circuit->u.p2p.neighbor = NULL;
hassof390d2c2004-09-10 20:48:21 +0000817 THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
818 }
Josh Bailey3f045a02012-03-24 08:35:20 -0700819
820 /* Cancel all active threads */
821 THREAD_TIMER_OFF (circuit->t_send_csnp[0]);
822 THREAD_TIMER_OFF (circuit->t_send_csnp[1]);
823 THREAD_TIMER_OFF (circuit->t_send_psnp[0]);
824 THREAD_TIMER_OFF (circuit->t_send_psnp[1]);
825 THREAD_OFF (circuit->t_read);
826
827 if (circuit->lsp_queue)
828 {
829 circuit->lsp_queue->del = NULL;
830 list_delete (circuit->lsp_queue);
831 circuit->lsp_queue = NULL;
832 }
833
834 /* send one gratuitous hello to spead up convergence */
835 if (circuit->is_type & IS_LEVEL_1)
836 send_hello (circuit, IS_LEVEL_1);
837 if (circuit->is_type & IS_LEVEL_2)
838 send_hello (circuit, IS_LEVEL_2);
839
840 circuit->upadjcount[0] = 0;
841 circuit->upadjcount[1] = 0;
842
jardineb5d44e2003-12-23 08:09:43 +0000843 /* close the socket */
Josh Bailey3f045a02012-03-24 08:35:20 -0700844 if (circuit->fd)
845 {
846 close (circuit->fd);
847 circuit->fd = 0;
848 }
849
850 if (circuit->rcv_stream != NULL)
851 {
852 stream_free (circuit->rcv_stream);
853 circuit->rcv_stream = NULL;
854 }
855
856 if (circuit->snd_stream != NULL)
857 {
858 stream_free (circuit->snd_stream);
859 circuit->snd_stream = NULL;
860 }
861
862 thread_cancel_event (master, circuit);
jardineb5d44e2003-12-23 08:09:43 +0000863
864 return;
865}
866
867void
868circuit_update_nlpids (struct isis_circuit *circuit)
869{
870 circuit->nlpids.count = 0;
hassof390d2c2004-09-10 20:48:21 +0000871
872 if (circuit->ip_router)
873 {
874 circuit->nlpids.nlpids[0] = NLPID_IP;
875 circuit->nlpids.count++;
876 }
jardineb5d44e2003-12-23 08:09:43 +0000877#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000878 if (circuit->ipv6_router)
879 {
880 circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
881 circuit->nlpids.count++;
882 }
jardineb5d44e2003-12-23 08:09:43 +0000883#endif /* HAVE_IPV6 */
884 return;
885}
886
Josh Bailey3f045a02012-03-24 08:35:20 -0700887void
888isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty,
889 char detail)
890{
891 if (detail == ISIS_UI_LEVEL_BRIEF)
892 {
893 vty_out (vty, " %-12s", circuit->interface->name);
894 vty_out (vty, "0x%-7x", circuit->circuit_id);
895 vty_out (vty, "%-9s", circuit_state2string (circuit->state));
896 vty_out (vty, "%-9s", circuit_type2string (circuit->circ_type));
897 vty_out (vty, "%-9s", circuit_t2string (circuit->is_type));
898 vty_out (vty, "%s", VTY_NEWLINE);
899 }
900
901 if (detail == ISIS_UI_LEVEL_DETAIL)
902 {
Christian Frankecb32a192015-11-10 18:33:13 +0100903 struct listnode *node;
904 struct prefix *ip_addr;
905 u_char buf[BUFSIZ];
906
Josh Bailey3f045a02012-03-24 08:35:20 -0700907 vty_out (vty, " Interface: %s", circuit->interface->name);
908 vty_out (vty, ", State: %s", circuit_state2string (circuit->state));
909 if (circuit->is_passive)
910 vty_out (vty, ", Passive");
911 else
912 vty_out (vty, ", Active");
913 vty_out (vty, ", Circuit Id: 0x%x", circuit->circuit_id);
914 vty_out (vty, "%s", VTY_NEWLINE);
915 vty_out (vty, " Type: %s", circuit_type2string (circuit->circ_type));
916 vty_out (vty, ", Level: %s", circuit_t2string (circuit->is_type));
917 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
918 vty_out (vty, ", SNPA: %-10s", snpa_print (circuit->u.bc.snpa));
919 vty_out (vty, "%s", VTY_NEWLINE);
920 if (circuit->is_type & IS_LEVEL_1)
921 {
922 vty_out (vty, " Level-1 Information:%s", VTY_NEWLINE);
923 if (circuit->area->newmetric)
924 vty_out (vty, " Metric: %d", circuit->te_metric[0]);
925 else
926 vty_out (vty, " Metric: %d",
927 circuit->metrics[0].metric_default);
928 if (!circuit->is_passive)
929 {
930 vty_out (vty, ", Active neighbors: %u%s",
931 circuit->upadjcount[0], VTY_NEWLINE);
932 vty_out (vty, " Hello interval: %u, "
933 "Holddown count: %u %s%s",
934 circuit->hello_interval[0],
935 circuit->hello_multiplier[0],
936 (circuit->pad_hellos ? "(pad)" : "(no-pad)"),
937 VTY_NEWLINE);
938 vty_out (vty, " CNSP interval: %u, "
939 "PSNP interval: %u%s",
940 circuit->csnp_interval[0],
941 circuit->psnp_interval[0], VTY_NEWLINE);
942 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
943 vty_out (vty, " LAN Priority: %u, %s%s",
944 circuit->priority[0],
945 (circuit->u.bc.is_dr[0] ? \
946 "is DIS" : "is not DIS"), VTY_NEWLINE);
947 }
948 else
949 {
950 vty_out (vty, "%s", VTY_NEWLINE);
951 }
952 }
953 if (circuit->is_type & IS_LEVEL_2)
954 {
955 vty_out (vty, " Level-2 Information:%s", VTY_NEWLINE);
956 if (circuit->area->newmetric)
957 vty_out (vty, " Metric: %d", circuit->te_metric[1]);
958 else
959 vty_out (vty, " Metric: %d",
960 circuit->metrics[1].metric_default);
961 if (!circuit->is_passive)
962 {
963 vty_out (vty, ", Active neighbors: %u%s",
964 circuit->upadjcount[1], VTY_NEWLINE);
965 vty_out (vty, " Hello interval: %u, "
966 "Holddown count: %u %s%s",
967 circuit->hello_interval[1],
968 circuit->hello_multiplier[1],
969 (circuit->pad_hellos ? "(pad)" : "(no-pad)"),
970 VTY_NEWLINE);
971 vty_out (vty, " CNSP interval: %u, "
972 "PSNP interval: %u%s",
973 circuit->csnp_interval[1],
974 circuit->psnp_interval[1], VTY_NEWLINE);
975 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
976 vty_out (vty, " LAN Priority: %u, %s%s",
977 circuit->priority[1],
978 (circuit->u.bc.is_dr[1] ? \
979 "is DIS" : "is not DIS"), VTY_NEWLINE);
980 }
981 else
982 {
983 vty_out (vty, "%s", VTY_NEWLINE);
984 }
985 }
986 if (circuit->ip_addrs && listcount (circuit->ip_addrs) > 0)
987 {
Josh Bailey3f045a02012-03-24 08:35:20 -0700988 vty_out (vty, " IP Prefix(es):%s", VTY_NEWLINE);
989 for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ip_addr))
990 {
991 prefix2str (ip_addr, (char*)buf, BUFSIZ),
992 vty_out (vty, " %s%s", buf, VTY_NEWLINE);
993 }
994 }
Christian Frankecb32a192015-11-10 18:33:13 +0100995 if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0)
996 {
997 vty_out(vty, " IPv6 Link-Locals:%s", VTY_NEWLINE);
998 for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ip_addr))
999 {
1000 prefix2str(ip_addr, (char*)buf, BUFSIZ),
1001 vty_out(vty, " %s%s", buf, VTY_NEWLINE);
1002 }
1003 }
1004 if (circuit->ipv6_link && listcount(circuit->ipv6_non_link) > 0)
1005 {
1006 vty_out(vty, " IPv6 Prefixes:%s", VTY_NEWLINE);
1007 for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip_addr))
1008 {
1009 prefix2str(ip_addr, (char*)buf, BUFSIZ),
1010 vty_out(vty, " %s%s", buf, VTY_NEWLINE);
1011 }
1012 }
1013
Josh Bailey3f045a02012-03-24 08:35:20 -07001014 vty_out (vty, "%s", VTY_NEWLINE);
1015 }
1016 return;
1017}
1018
jardineb5d44e2003-12-23 08:09:43 +00001019int
hassof390d2c2004-09-10 20:48:21 +00001020isis_interface_config_write (struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +00001021{
jardineb5d44e2003-12-23 08:09:43 +00001022 int write = 0;
hasso3fdb2dd2005-09-28 18:45:54 +00001023 struct listnode *node, *node2;
jardineb5d44e2003-12-23 08:09:43 +00001024 struct interface *ifp;
1025 struct isis_area *area;
Josh Bailey3f045a02012-03-24 08:35:20 -07001026 struct isis_circuit *circuit;
jardineb5d44e2003-12-23 08:09:43 +00001027 int i;
jardineb5d44e2003-12-23 08:09:43 +00001028
hasso3fdb2dd2005-09-28 18:45:54 +00001029 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
jardineb5d44e2003-12-23 08:09:43 +00001030 {
Josh Bailey3f045a02012-03-24 08:35:20 -07001031 /* IF name */
1032 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1033 write++;
1034 /* IF desc */
1035 if (ifp->desc)
1036 {
1037 vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
1038 write++;
1039 }
1040 /* ISIS Circuit */
1041 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node2, area))
1042 {
1043 circuit = circuit_lookup_by_ifp (ifp, area->circuit_list);
1044 if (circuit == NULL)
1045 continue;
1046 if (circuit->ip_router)
1047 {
1048 vty_out (vty, " ip router isis %s%s", area->area_tag,
1049 VTY_NEWLINE);
1050 write++;
1051 }
1052 if (circuit->is_passive)
1053 {
1054 vty_out (vty, " isis passive%s", VTY_NEWLINE);
1055 write++;
1056 }
1057 if (circuit->circ_type_config == CIRCUIT_T_P2P)
1058 {
1059 vty_out (vty, " isis network point-to-point%s", VTY_NEWLINE);
1060 write++;
1061 }
jardineb5d44e2003-12-23 08:09:43 +00001062#ifdef HAVE_IPV6
Josh Bailey3f045a02012-03-24 08:35:20 -07001063 if (circuit->ipv6_router)
1064 {
1065 vty_out (vty, " ipv6 router isis %s%s", area->area_tag,
1066 VTY_NEWLINE);
1067 write++;
1068 }
jardineb5d44e2003-12-23 08:09:43 +00001069#endif /* HAVE_IPV6 */
jardineb5d44e2003-12-23 08:09:43 +00001070
Josh Bailey3f045a02012-03-24 08:35:20 -07001071 /* ISIS - circuit type */
1072 if (circuit->is_type == IS_LEVEL_1)
1073 {
1074 vty_out (vty, " isis circuit-type level-1%s", VTY_NEWLINE);
1075 write++;
1076 }
1077 else
1078 {
1079 if (circuit->is_type == IS_LEVEL_2)
1080 {
1081 vty_out (vty, " isis circuit-type level-2-only%s",
1082 VTY_NEWLINE);
1083 write++;
1084 }
1085 }
jardineb5d44e2003-12-23 08:09:43 +00001086
Josh Bailey3f045a02012-03-24 08:35:20 -07001087 /* ISIS - CSNP interval */
1088 if (circuit->csnp_interval[0] == circuit->csnp_interval[1])
1089 {
1090 if (circuit->csnp_interval[0] != DEFAULT_CSNP_INTERVAL)
1091 {
1092 vty_out (vty, " isis csnp-interval %d%s",
1093 circuit->csnp_interval[0], VTY_NEWLINE);
1094 write++;
1095 }
1096 }
1097 else
1098 {
1099 for (i = 0; i < 2; i++)
1100 {
1101 if (circuit->csnp_interval[i] != DEFAULT_CSNP_INTERVAL)
1102 {
1103 vty_out (vty, " isis csnp-interval %d level-%d%s",
1104 circuit->csnp_interval[i], i + 1, VTY_NEWLINE);
1105 write++;
1106 }
1107 }
1108 }
jardineb5d44e2003-12-23 08:09:43 +00001109
Josh Bailey3f045a02012-03-24 08:35:20 -07001110 /* ISIS - PSNP interval */
1111 if (circuit->psnp_interval[0] == circuit->psnp_interval[1])
1112 {
1113 if (circuit->psnp_interval[0] != DEFAULT_PSNP_INTERVAL)
1114 {
1115 vty_out (vty, " isis psnp-interval %d%s",
1116 circuit->psnp_interval[0], VTY_NEWLINE);
1117 write++;
1118 }
1119 }
1120 else
1121 {
1122 for (i = 0; i < 2; i++)
1123 {
1124 if (circuit->psnp_interval[i] != DEFAULT_PSNP_INTERVAL)
1125 {
1126 vty_out (vty, " isis psnp-interval %d level-%d%s",
1127 circuit->psnp_interval[i], i + 1, VTY_NEWLINE);
1128 write++;
1129 }
1130 }
1131 }
jardineb5d44e2003-12-23 08:09:43 +00001132
Josh Bailey3f045a02012-03-24 08:35:20 -07001133 /* ISIS - Hello padding - Defaults to true so only display if false */
1134 if (circuit->pad_hellos == 0)
1135 {
1136 vty_out (vty, " no isis hello padding%s", VTY_NEWLINE);
1137 write++;
1138 }
jardineb5d44e2003-12-23 08:09:43 +00001139
Josh Bailey3f045a02012-03-24 08:35:20 -07001140 /* ISIS - Hello interval */
1141 if (circuit->hello_interval[0] == circuit->hello_interval[1])
1142 {
1143 if (circuit->hello_interval[0] != DEFAULT_HELLO_INTERVAL)
1144 {
1145 vty_out (vty, " isis hello-interval %d%s",
1146 circuit->hello_interval[0], VTY_NEWLINE);
1147 write++;
1148 }
1149 }
1150 else
1151 {
1152 for (i = 0; i < 2; i++)
1153 {
1154 if (circuit->hello_interval[i] != DEFAULT_HELLO_INTERVAL)
1155 {
1156 vty_out (vty, " isis hello-interval %d level-%d%s",
1157 circuit->hello_interval[i], i + 1, VTY_NEWLINE);
1158 write++;
1159 }
1160 }
1161 }
jardineb5d44e2003-12-23 08:09:43 +00001162
Josh Bailey3f045a02012-03-24 08:35:20 -07001163 /* ISIS - Hello Multiplier */
1164 if (circuit->hello_multiplier[0] == circuit->hello_multiplier[1])
1165 {
1166 if (circuit->hello_multiplier[0] != DEFAULT_HELLO_MULTIPLIER)
1167 {
1168 vty_out (vty, " isis hello-multiplier %d%s",
1169 circuit->hello_multiplier[0], VTY_NEWLINE);
1170 write++;
1171 }
1172 }
1173 else
1174 {
1175 for (i = 0; i < 2; i++)
1176 {
1177 if (circuit->hello_multiplier[i] != DEFAULT_HELLO_MULTIPLIER)
1178 {
1179 vty_out (vty, " isis hello-multiplier %d level-%d%s",
1180 circuit->hello_multiplier[i], i + 1,
1181 VTY_NEWLINE);
1182 write++;
1183 }
1184 }
1185 }
1186
1187 /* ISIS - Priority */
1188 if (circuit->priority[0] == circuit->priority[1])
1189 {
1190 if (circuit->priority[0] != DEFAULT_PRIORITY)
1191 {
1192 vty_out (vty, " isis priority %d%s",
1193 circuit->priority[0], VTY_NEWLINE);
1194 write++;
1195 }
1196 }
1197 else
1198 {
1199 for (i = 0; i < 2; i++)
1200 {
1201 if (circuit->priority[i] != DEFAULT_PRIORITY)
1202 {
1203 vty_out (vty, " isis priority %d level-%d%s",
1204 circuit->priority[i], i + 1, VTY_NEWLINE);
1205 write++;
1206 }
1207 }
1208 }
1209
1210 /* ISIS - Metric */
1211 if (circuit->te_metric[0] == circuit->te_metric[1])
1212 {
1213 if (circuit->te_metric[0] != DEFAULT_CIRCUIT_METRIC)
1214 {
1215 vty_out (vty, " isis metric %d%s", circuit->te_metric[0],
1216 VTY_NEWLINE);
1217 write++;
1218 }
1219 }
1220 else
1221 {
1222 for (i = 0; i < 2; i++)
1223 {
1224 if (circuit->te_metric[i] != DEFAULT_CIRCUIT_METRIC)
1225 {
1226 vty_out (vty, " isis metric %d level-%d%s",
1227 circuit->te_metric[i], i + 1, VTY_NEWLINE);
1228 write++;
1229 }
1230 }
1231 }
1232 if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5)
1233 {
1234 vty_out (vty, " isis password md5 %s%s", circuit->passwd.passwd,
1235 VTY_NEWLINE);
1236 write++;
1237 }
1238 else if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT)
1239 {
1240 vty_out (vty, " isis password clear %s%s", circuit->passwd.passwd,
1241 VTY_NEWLINE);
1242 write++;
1243 }
1244 }
1245 vty_out (vty, "!%s", VTY_NEWLINE);
jardineb5d44e2003-12-23 08:09:43 +00001246 }
hassof390d2c2004-09-10 20:48:21 +00001247
jardineb5d44e2003-12-23 08:09:43 +00001248 return write;
1249}
jardineb5d44e2003-12-23 08:09:43 +00001250
David Lamparter3732cba2016-07-29 16:19:40 +02001251struct isis_circuit *
1252isis_circuit_create (struct isis_area *area, struct interface *ifp)
jardineb5d44e2003-12-23 08:09:43 +00001253{
Josh Bailey3f045a02012-03-24 08:35:20 -07001254 struct isis_circuit *circuit;
David Lamparter3732cba2016-07-29 16:19:40 +02001255 circuit = isis_csm_state_change (ISIS_ENABLE, NULL, area);
1256 assert (circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
1257 isis_circuit_if_bind (circuit, ifp);
1258 return circuit;
jardineb5d44e2003-12-23 08:09:43 +00001259}
1260
David Lamparter3732cba2016-07-29 16:19:40 +02001261void
1262isis_circuit_af_set (struct isis_circuit *circuit, bool ip_router, bool ipv6_router)
jardineb5d44e2003-12-23 08:09:43 +00001263{
David Lamparter3732cba2016-07-29 16:19:40 +02001264 struct isis_area *area = circuit->area;
1265 bool change = circuit->ip_router != ip_router || circuit->ipv6_router != ipv6_router;
1266 bool was_enabled = circuit->ip_router || circuit->ipv6_router;
jardineb5d44e2003-12-23 08:09:43 +00001267
David Lamparter3732cba2016-07-29 16:19:40 +02001268 area->ip_circuits += ip_router - circuit->ip_router;
1269 area->ipv6_circuits += ipv6_router - circuit->ipv6_router;
1270 circuit->ip_router = ip_router;
1271 circuit->ipv6_router = ipv6_router;
hassof390d2c2004-09-10 20:48:21 +00001272
David Lamparter3732cba2016-07-29 16:19:40 +02001273 if (!change)
1274 return;
Josh Bailey3f045a02012-03-24 08:35:20 -07001275
David Lamparter3732cba2016-07-29 16:19:40 +02001276 circuit_update_nlpids (circuit);
Josh Bailey3f045a02012-03-24 08:35:20 -07001277
David Lamparter3732cba2016-07-29 16:19:40 +02001278 if (!ip_router && !ipv6_router)
jardineb5d44e2003-12-23 08:09:43 +00001279 isis_csm_state_change (ISIS_DISABLE, circuit, area);
David Lamparter3732cba2016-07-29 16:19:40 +02001280 else if (!was_enabled)
1281 isis_csm_state_change (ISIS_ENABLE, circuit, area);
Christian Franke84a4da02016-04-03 12:46:27 -03001282 else
Christian Franke84a4da02016-04-03 12:46:27 -03001283 lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
Josh Bailey3f045a02012-03-24 08:35:20 -07001284}
1285
David Lamparter3732cba2016-07-29 16:19:40 +02001286int
1287isis_circuit_passive_set (struct isis_circuit *circuit, bool passive)
Josh Bailey3f045a02012-03-24 08:35:20 -07001288{
David Lamparter3732cba2016-07-29 16:19:40 +02001289 if (circuit->is_passive == passive)
1290 return 0;
Josh Bailey3f045a02012-03-24 08:35:20 -07001291
David Lamparter3732cba2016-07-29 16:19:40 +02001292 if (if_is_loopback (circuit->interface) && !passive)
1293 return -1;
Josh Bailey3f045a02012-03-24 08:35:20 -07001294
1295 if (circuit->state != C_STATE_UP)
1296 {
David Lamparter3732cba2016-07-29 16:19:40 +02001297 circuit->is_passive = passive;
Josh Bailey3f045a02012-03-24 08:35:20 -07001298 }
1299 else
1300 {
1301 struct isis_area *area = circuit->area;
1302 isis_csm_state_change (ISIS_DISABLE, circuit, area);
David Lamparter3732cba2016-07-29 16:19:40 +02001303 circuit->is_passive = passive;
Josh Bailey3f045a02012-03-24 08:35:20 -07001304 isis_csm_state_change (ISIS_ENABLE, circuit, area);
1305 }
1306
David Lamparter3732cba2016-07-29 16:19:40 +02001307 return 0;
Josh Bailey3f045a02012-03-24 08:35:20 -07001308}
1309
David Lamparter3732cba2016-07-29 16:19:40 +02001310void
1311isis_circuit_is_type_set (struct isis_circuit *circuit, int circ_type)
Josh Bailey3f045a02012-03-24 08:35:20 -07001312{
David Lamparter3732cba2016-07-29 16:19:40 +02001313 if (circuit->circ_type != circ_type)
1314 isis_event_circuit_type_change (circuit, circ_type);
Josh Bailey3f045a02012-03-24 08:35:20 -07001315}
1316
David Lamparter3732cba2016-07-29 16:19:40 +02001317int
1318isis_circuit_metric_set (struct isis_circuit *circuit, int level, int metric)
jardineb5d44e2003-12-23 08:09:43 +00001319{
David Lamparter3732cba2016-07-29 16:19:40 +02001320 assert (level == IS_LEVEL_1 || level == IS_LEVEL_2);
1321 if (metric > MAX_WIDE_LINK_METRIC)
1322 return -1;
1323 if (circuit->area && circuit->area->oldmetric
1324 && metric > MAX_NARROW_LINK_METRIC)
1325 return -1;
hassof390d2c2004-09-10 20:48:21 +00001326
David Lamparter3732cba2016-07-29 16:19:40 +02001327 circuit->te_metric[level - 1] = metric;
1328 circuit->metrics[level - 1].metric_default = metric;
hassof390d2c2004-09-10 20:48:21 +00001329
David Lamparter3732cba2016-07-29 16:19:40 +02001330 if (circuit->area)
1331 lsp_regenerate_schedule (circuit->area, level, 0);
1332 return 0;
jardineb5d44e2003-12-23 08:09:43 +00001333}
1334
Christian Frankef5fbfb22016-07-28 17:23:27 +02001335int
1336isis_circuit_passwd_unset (struct isis_circuit *circuit)
jardineb5d44e2003-12-23 08:09:43 +00001337{
Christian Frankef5fbfb22016-07-28 17:23:27 +02001338 memset(&circuit->passwd, 0, sizeof(circuit->passwd));
1339 return 0;
Josh Bailey3f045a02012-03-24 08:35:20 -07001340}
1341
Christian Frankef5fbfb22016-07-28 17:23:27 +02001342static int
1343isis_circuit_passwd_set (struct isis_circuit *circuit, u_char passwd_type, const char *passwd)
Josh Bailey3f045a02012-03-24 08:35:20 -07001344{
1345 int len;
Josh Bailey3f045a02012-03-24 08:35:20 -07001346
Christian Frankef5fbfb22016-07-28 17:23:27 +02001347 if (!passwd)
1348 return -1;
1349
1350 len = strlen(passwd);
Josh Bailey3f045a02012-03-24 08:35:20 -07001351 if (len > 254)
Christian Frankef5fbfb22016-07-28 17:23:27 +02001352 return -1;
hassof390d2c2004-09-10 20:48:21 +00001353
Christian Frankef5fbfb22016-07-28 17:23:27 +02001354 circuit->passwd.len = len;
1355 strncpy((char *)circuit->passwd.passwd, passwd, 255);
1356 circuit->passwd.type = passwd_type;
1357 return 0;
jardineb5d44e2003-12-23 08:09:43 +00001358}
1359
Christian Frankef5fbfb22016-07-28 17:23:27 +02001360int
1361isis_circuit_passwd_cleartext_set (struct isis_circuit *circuit, const char *passwd)
jardineb5d44e2003-12-23 08:09:43 +00001362{
Christian Frankef5fbfb22016-07-28 17:23:27 +02001363 return isis_circuit_passwd_set (circuit, ISIS_PASSWD_TYPE_CLEARTXT, passwd);
1364}
hassof390d2c2004-09-10 20:48:21 +00001365
Christian Frankef5fbfb22016-07-28 17:23:27 +02001366int
1367isis_circuit_passwd_hmac_md5_set (struct isis_circuit *circuit, const char *passwd)
1368{
1369 return isis_circuit_passwd_set (circuit, ISIS_PASSWD_TYPE_HMAC_MD5, passwd);
jardineb5d44e2003-12-23 08:09:43 +00001370}
Josh Bailey3f045a02012-03-24 08:35:20 -07001371struct cmd_node interface_node = {
jardineb5d44e2003-12-23 08:09:43 +00001372 INTERFACE_NODE,
1373 "%s(config-if)# ",
1374 1,
1375};
1376
David Lamparter3732cba2016-07-29 16:19:40 +02001377int
1378isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type)
Josh Bailey3f045a02012-03-24 08:35:20 -07001379{
David Lamparter3732cba2016-07-29 16:19:40 +02001380 /* Changing the network type to/of loopback or unknown interfaces
1381 * is not supported. */
1382 if (circ_type == CIRCUIT_T_UNKNOWN
1383 || circ_type == CIRCUIT_T_LOOPBACK
1384 || circuit->circ_type == CIRCUIT_T_UNKNOWN
1385 || circuit->circ_type == CIRCUIT_T_LOOPBACK)
1386 {
1387 if (circuit->circ_type != circ_type)
1388 return -1;
1389 else
1390 return 0;
1391 }
Josh Bailey3f045a02012-03-24 08:35:20 -07001392
David Lamparter3732cba2016-07-29 16:19:40 +02001393 if (circuit->circ_type == circ_type)
1394 return 0;
Josh Bailey3f045a02012-03-24 08:35:20 -07001395
1396 if (circuit->state != C_STATE_UP)
1397 {
David Lamparter3732cba2016-07-29 16:19:40 +02001398 circuit->circ_type = circ_type;
1399 circuit->circ_type_config = circ_type;
Josh Bailey3f045a02012-03-24 08:35:20 -07001400 }
1401 else
1402 {
1403 struct isis_area *area = circuit->area;
David Lamparter3732cba2016-07-29 16:19:40 +02001404 if (circ_type == CIRCUIT_T_BROADCAST
1405 && !if_is_broadcast(circuit->interface))
1406 return -1;
Josh Bailey3f045a02012-03-24 08:35:20 -07001407
David Lamparter3732cba2016-07-29 16:19:40 +02001408 isis_csm_state_change(ISIS_DISABLE, circuit, area);
1409 circuit->circ_type = circ_type;
1410 circuit->circ_type_config = circ_type;
1411 isis_csm_state_change(ISIS_ENABLE, circuit, area);
Josh Bailey3f045a02012-03-24 08:35:20 -07001412 }
David Lamparter3732cba2016-07-29 16:19:40 +02001413 return 0;
Josh Bailey3f045a02012-03-24 08:35:20 -07001414}
1415
jardineb5d44e2003-12-23 08:09:43 +00001416int
1417isis_if_new_hook (struct interface *ifp)
1418{
jardineb5d44e2003-12-23 08:09:43 +00001419 return 0;
1420}
1421
1422int
1423isis_if_delete_hook (struct interface *ifp)
1424{
Subbaiah Venkatae38e0df2012-03-27 23:48:05 -07001425 struct isis_circuit *circuit;
1426 /* Clean up the circuit data */
1427 if (ifp && ifp->info)
1428 {
1429 circuit = ifp->info;
1430 isis_csm_state_change (IF_DOWN_FROM_Z, circuit, circuit->area);
1431 isis_csm_state_change (ISIS_DISABLE, circuit, circuit->area);
1432 }
1433
jardineb5d44e2003-12-23 08:09:43 +00001434 return 0;
1435}
1436
jardineb5d44e2003-12-23 08:09:43 +00001437void
1438isis_circuit_init ()
1439{
jardineb5d44e2003-12-23 08:09:43 +00001440 /* Initialize Zebra interface data structure */
jardineb5d44e2003-12-23 08:09:43 +00001441 if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
1442 if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
1443
1444 /* Install interface node */
1445 install_node (&interface_node, isis_interface_config_write);
1446 install_element (CONFIG_NODE, &interface_cmd);
Subbaiah Venkatae38e0df2012-03-27 23:48:05 -07001447 install_element (CONFIG_NODE, &no_interface_cmd);
jardineb5d44e2003-12-23 08:09:43 +00001448
1449 install_default (INTERFACE_NODE);
1450 install_element (INTERFACE_NODE, &interface_desc_cmd);
1451 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1452
David Lamparter3732cba2016-07-29 16:19:40 +02001453 isis_vty_init ();
jardineb5d44e2003-12-23 08:09:43 +00001454}