blob: 814a8e85836e5ea5938054fca13cc445489e01a7 [file] [log] [blame]
Olivier Dugeon4f593572016-04-19 19:03:05 +02001/*
2 * IS-IS Rout(e)ing protocol - isis_te.c
3 *
4 * This is an implementation of RFC5305
5 *
6 * Copyright (C) 2014 Orange Labs
7 * http://www.orange.com
8 *
9 * This file is part of GNU Zebra.
10 *
11 * GNU Zebra is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2, or (at your option) any
14 * later version.
15 *
16 * GNU Zebra is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with GNU Zebra; see the file COPYING. If not, write to the Free
23 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 * 02111-1307, USA.
25 */
26
27#include <zebra.h>
28#include <math.h>
29
30#include "linklist.h"
31#include "thread.h"
32#include "vty.h"
33#include "stream.h"
34#include "memory.h"
35#include "log.h"
36#include "prefix.h"
37#include "command.h"
38#include "hash.h"
39#include "if.h"
40#include "checksum.h"
41#include "md5.h"
42#include "sockunion.h"
43#include "network.h"
44
45#include "isisd/dict.h"
46#include "isisd/isis_constants.h"
47#include "isisd/isis_common.h"
48#include "isisd/isis_flags.h"
49#include "isisd/isis_circuit.h"
50#include "isisd/isisd.h"
51#include "isisd/isis_tlv.h"
52#include "isisd/isis_lsp.h"
53#include "isisd/isis_pdu.h"
54#include "isisd/isis_dynhn.h"
55#include "isisd/isis_misc.h"
56#include "isisd/isis_csm.h"
57#include "isisd/isis_adjacency.h"
58#include "isisd/isis_spf.h"
59#include "isisd/isis_te.h"
60
61/* Global varial for MPLS TE management */
62struct isis_mpls_te isisMplsTE;
63
64const char *mode2text[] = { "Disable", "Area", "AS", "Emulate" };
65
66/*------------------------------------------------------------------------*
67 * Followings are control functions for MPLS-TE parameters management.
68 *------------------------------------------------------------------------*/
69
70/* Search MPLS TE Circuit context from Interface */
71static struct mpls_te_circuit *
72lookup_mpls_params_by_ifp (struct interface *ifp)
73{
74 struct isis_circuit *circuit;
75
76 if ((circuit = circuit_scan_by_ifp (ifp)) == NULL)
77 return NULL;
78
79 return circuit->mtc;
80}
81
82/* Create new MPLS TE Circuit context */
83struct mpls_te_circuit *
84mpls_te_circuit_new()
85{
86 struct mpls_te_circuit *mtc;
87
88 zlog_debug ("ISIS MPLS-TE: Create new MPLS TE Circuit context");
89
90 mtc = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof (struct mpls_te_circuit));
91
92 if (mtc == NULL)
93 return NULL;
94
95 mtc->status = disable;
96 mtc->type = STD_TE;
97 mtc->length = 0;
98
99 return mtc;
100
101}
102
103/* Copy SUB TLVs parameters into a buffer - No space verification are performed */
104/* Caller must verify before that there is enough free space in the buffer */
105u_char
106add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc)
107{
108 u_char size, *tlvs = buf;
109
110 zlog_debug ("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
111
112 if (mtc == NULL)
113 {
114 zlog_debug("ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified");
115 return 0;
116 }
117
118 /* Create buffer if not provided */
119 if (buf == NULL)
120 {
121 zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified");
122 return 0;
123 }
124
125 /* TE_SUBTLV_ADMIN_GRP */
126 if (SUBTLV_TYPE(mtc->admin_grp) != 0)
127 {
128 size = SUBTLV_SIZE (&(mtc->admin_grp.header));
129 memcpy(tlvs, &(mtc->admin_grp), size);
130 tlvs += size;
131 }
132
133 /* TE_SUBTLV_LLRI */
134 if (SUBTLV_TYPE(mtc->llri) != 0)
135 {
136 size = SUBTLV_SIZE (&(mtc->llri.header));
137 memcpy(tlvs, &(mtc->llri), size);
138 tlvs += size;
139 }
140
141 /* TE_SUBTLV_LCLIF_IPADDR */
142 if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
143 {
144 size = SUBTLV_SIZE (&(mtc->local_ipaddr.header));
145 memcpy(tlvs, &(mtc->local_ipaddr), size);
146 tlvs += size;
147 }
148
149 /* TE_SUBTLV_RMTIF_IPADDR */
150 if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
151 {
152 size = SUBTLV_SIZE (&(mtc->rmt_ipaddr.header));
153 memcpy(tlvs, &(mtc->rmt_ipaddr), size);
154 tlvs += size;
155 }
156
157 /* TE_SUBTLV_MAX_BW */
158 if (SUBTLV_TYPE(mtc->max_bw) != 0)
159 {
160 size = SUBTLV_SIZE (&(mtc->max_bw.header));
161 memcpy(tlvs, &(mtc->max_bw), size);
162 tlvs += size;
163 }
164
165 /* TE_SUBTLV_MAX_RSV_BW */
166 if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0)
167 {
168 size = SUBTLV_SIZE (&(mtc->max_rsv_bw.header));
169 memcpy(tlvs, &(mtc->max_rsv_bw), size);
170 tlvs += size;
171 }
172
173 /* TE_SUBTLV_UNRSV_BW */
174 if (SUBTLV_TYPE(mtc->unrsv_bw) != 0)
175 {
176 size = SUBTLV_SIZE (&(mtc->unrsv_bw.header));
177 memcpy(tlvs, &(mtc->unrsv_bw), size);
178 tlvs += size;
179 }
180
181 /* TE_SUBTLV_TE_METRIC */
182 if (SUBTLV_TYPE(mtc->te_metric) != 0)
183 {
184 size = SUBTLV_SIZE (&(mtc->te_metric.header));
185 memcpy(tlvs, &(mtc->te_metric), size);
186 tlvs += size;
187 }
188
189 /* TE_SUBTLV_AV_DELAY */
190 if (SUBTLV_TYPE(mtc->av_delay) != 0)
191 {
192 size = SUBTLV_SIZE (&(mtc->av_delay.header));
193 memcpy(tlvs, &(mtc->av_delay), size);
194 tlvs += size;
195 }
196
197 /* TE_SUBTLV_MM_DELAY */
198 if (SUBTLV_TYPE(mtc->mm_delay) != 0)
199 {
200 size = SUBTLV_SIZE (&(mtc->mm_delay.header));
201 memcpy(tlvs, &(mtc->mm_delay), size);
202 tlvs += size;
203 }
204
205 /* TE_SUBTLV_DELAY_VAR */
206 if (SUBTLV_TYPE(mtc->delay_var) != 0)
207 {
208 size = SUBTLV_SIZE (&(mtc->delay_var.header));
209 memcpy(tlvs, &(mtc->delay_var), size);
210 tlvs += size;
211 }
212
213 /* TE_SUBTLV_PKT_LOSS */
214 if (SUBTLV_TYPE(mtc->pkt_loss) != 0)
215 {
216 size = SUBTLV_SIZE (&(mtc->pkt_loss.header));
217 memcpy(tlvs, &(mtc->pkt_loss), size);
218 tlvs += size;
219 }
220
221 /* TE_SUBTLV_RES_BW */
222 if (SUBTLV_TYPE(mtc->res_bw) != 0)
223 {
224 size = SUBTLV_SIZE (&(mtc->res_bw.header));
225 memcpy(tlvs, &(mtc->res_bw), size);
226 tlvs += size;
227 }
228
229 /* TE_SUBTLV_AVA_BW */
230 if (SUBTLV_TYPE(mtc->ava_bw) != 0)
231 {
232 size = SUBTLV_SIZE (&(mtc->ava_bw.header));
233 memcpy(tlvs, &(mtc->ava_bw), size);
234 tlvs += size;
235 }
236
237 /* TE_SUBTLV_USE_BW */
238 if (SUBTLV_TYPE(mtc->use_bw) != 0)
239 {
240 size = SUBTLV_SIZE (&(mtc->use_bw.header));
241 memcpy(tlvs, &(mtc->use_bw), size);
242 tlvs += size;
243 }
244
245 /* Update SubTLVs length */
246 mtc->length = subtlvs_len(mtc);
247
248 zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc->length);
249
250 return mtc->length;
251}
252
253/* Compute total Sub-TLVs size */
254u_char
255subtlvs_len (struct mpls_te_circuit *mtc)
256{
257 int length = 0;
258
259 /* Sanity Check */
260 if (mtc == NULL)
261 return 0;
262
263 /* TE_SUBTLV_ADMIN_GRP */
264 if (SUBTLV_TYPE(mtc->admin_grp) != 0)
265 length += SUBTLV_SIZE (&(mtc->admin_grp.header));
266
267 /* TE_SUBTLV_LLRI */
268 if (SUBTLV_TYPE(mtc->llri) != 0)
269 length += SUBTLV_SIZE (&mtc->llri.header);
270
271 /* TE_SUBTLV_LCLIF_IPADDR */
272 if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
273 length += SUBTLV_SIZE (&mtc->local_ipaddr.header);
274
275 /* TE_SUBTLV_RMTIF_IPADDR */
276 if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
277 length += SUBTLV_SIZE (&mtc->rmt_ipaddr.header);
278
279 /* TE_SUBTLV_MAX_BW */
280 if (SUBTLV_TYPE(mtc->max_bw) != 0)
281 length += SUBTLV_SIZE (&mtc->max_bw.header);
282
283 /* TE_SUBTLV_MAX_RSV_BW */
284 if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0)
285 length += SUBTLV_SIZE (&mtc->max_rsv_bw.header);
286
287 /* TE_SUBTLV_UNRSV_BW */
288 if (SUBTLV_TYPE(mtc->unrsv_bw) != 0)
289 length += SUBTLV_SIZE (&mtc->unrsv_bw.header);
290
291 /* TE_SUBTLV_TE_METRIC */
292 if (SUBTLV_TYPE(mtc->te_metric) != 0)
293 length += SUBTLV_SIZE (&mtc->te_metric.header);
294
295 /* TE_SUBTLV_AV_DELAY */
296 if (SUBTLV_TYPE(mtc->av_delay) != 0)
297 length += SUBTLV_SIZE (&mtc->av_delay.header);
298
299 /* TE_SUBTLV_MM_DELAY */
300 if (SUBTLV_TYPE(mtc->mm_delay) != 0)
301 length += SUBTLV_SIZE (&mtc->mm_delay.header);
302
303 /* TE_SUBTLV_DELAY_VAR */
304 if (SUBTLV_TYPE(mtc->delay_var) != 0)
305 length += SUBTLV_SIZE (&mtc->delay_var.header);
306
307 /* TE_SUBTLV_PKT_LOSS */
308 if (SUBTLV_TYPE(mtc->pkt_loss) != 0)
309 length += SUBTLV_SIZE (&mtc->pkt_loss.header);
310
311 /* TE_SUBTLV_RES_BW */
312 if (SUBTLV_TYPE(mtc->res_bw) != 0)
313 length += SUBTLV_SIZE (&mtc->res_bw.header);
314
315 /* TE_SUBTLV_AVA_BW */
316 if (SUBTLV_TYPE(mtc->ava_bw) != 0)
317 length += SUBTLV_SIZE (&mtc->ava_bw.header);
318
319 /* TE_SUBTLV_USE_BW */
320 if (SUBTLV_TYPE(mtc->use_bw) != 0)
321 length += SUBTLV_SIZE (&mtc->use_bw.header);
322
323 /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */
324 if (length > MAX_SUBTLV_SIZE)
325 {
326 mtc->length = 0;
327 return 0;
328 }
329
330 mtc->length = (u_char)length;
331
332 return mtc->length;
333}
334
335/* Following are various functions to set MPLS TE parameters */
336static void
337set_circuitparams_admin_grp (struct mpls_te_circuit *mtc, u_int32_t admingrp)
338{
339 SUBTLV_TYPE(mtc->admin_grp) = TE_SUBTLV_ADMIN_GRP;
340 SUBTLV_LEN(mtc->admin_grp) = SUBTLV_DEF_SIZE;
341 mtc->admin_grp.value = htonl(admingrp);
342 return;
343}
344
345static void __attribute__ ((unused))
346set_circuitparams_llri (struct mpls_te_circuit *mtc, u_int32_t local, u_int32_t remote)
347{
348 SUBTLV_TYPE(mtc->llri) = TE_SUBTLV_LLRI;
349 SUBTLV_LEN(mtc->llri) = TE_SUBTLV_LLRI_SIZE;
350 mtc->llri.local = htonl(local);
351 mtc->llri.remote = htonl(remote);
352}
353
354void
355set_circuitparams_local_ipaddr (struct mpls_te_circuit *mtc, struct in_addr addr)
356{
357
358 SUBTLV_TYPE(mtc->local_ipaddr) = TE_SUBTLV_LOCAL_IPADDR;
359 SUBTLV_LEN(mtc->local_ipaddr) = SUBTLV_DEF_SIZE;
360 mtc->local_ipaddr.value.s_addr = addr.s_addr;
361 return;
362}
363
364void
365set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *mtc, struct in_addr addr)
366{
367
368 SUBTLV_TYPE(mtc->rmt_ipaddr) = TE_SUBTLV_RMT_IPADDR;
369 SUBTLV_LEN(mtc->rmt_ipaddr) = SUBTLV_DEF_SIZE;
370 mtc->rmt_ipaddr.value.s_addr = addr.s_addr;
371 return;
372}
373
374static void
375set_circuitparams_max_bw (struct mpls_te_circuit *mtc, float fp)
376{
377 SUBTLV_TYPE(mtc->max_bw) = TE_SUBTLV_MAX_BW;
378 SUBTLV_LEN(mtc->max_bw) = SUBTLV_DEF_SIZE;
379 mtc->max_bw.value = htonf(fp);
380 return;
381}
382
383static void
384set_circuitparams_max_rsv_bw (struct mpls_te_circuit *mtc, float fp)
385{
386 SUBTLV_TYPE(mtc->max_rsv_bw) = TE_SUBTLV_MAX_RSV_BW;
387 SUBTLV_LEN(mtc->max_rsv_bw) = SUBTLV_DEF_SIZE;
388 mtc->max_rsv_bw.value = htonf(fp);
389 return;
390}
391
392static void
393set_circuitparams_unrsv_bw (struct mpls_te_circuit *mtc, int priority, float fp)
394{
395 /* Note that TLV-length field is the size of array. */
396 SUBTLV_TYPE(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_BW;
397 SUBTLV_LEN(mtc->unrsv_bw) = TE_SUBTLV_UNRSV_SIZE;
398 mtc->unrsv_bw.value[priority] = htonf(fp);
399 return;
400}
401
402static void
403set_circuitparams_te_metric (struct mpls_te_circuit *mtc, u_int32_t te_metric)
404{
405 SUBTLV_TYPE(mtc->te_metric) = TE_SUBTLV_TE_METRIC;
406 SUBTLV_LEN(mtc->te_metric) = TE_SUBTLV_TE_METRIC_SIZE;
407 mtc->te_metric.value[0] = (te_metric >> 16) & 0xFF;
408 mtc->te_metric.value[1] = (te_metric >> 8) & 0xFF;
409 mtc->te_metric.value[2] = te_metric & 0xFF;
410 return;
411}
412
413static void
414set_circuitparams_inter_as (struct mpls_te_circuit *mtc, struct in_addr addr, u_int32_t as)
415{
416
417 /* Set the Remote ASBR IP address and then the associated AS number */
418 SUBTLV_TYPE(mtc->rip) = TE_SUBTLV_RIP;
419 SUBTLV_LEN(mtc->rip) = SUBTLV_DEF_SIZE;
420 mtc->rip.value.s_addr = addr.s_addr;
421
422 SUBTLV_TYPE(mtc->ras) = TE_SUBTLV_RAS;
423 SUBTLV_LEN(mtc->ras) = SUBTLV_DEF_SIZE;
424 mtc->ras.value = htonl(as);
425}
426
427static void
428unset_circuitparams_inter_as (struct mpls_te_circuit *mtc)
429{
430
431 /* Reset the Remote ASBR IP address and then the associated AS number */
432 SUBTLV_TYPE(mtc->rip) = 0;
433 SUBTLV_LEN(mtc->rip) = 0;
434 mtc->rip.value.s_addr = 0;
435
436 SUBTLV_TYPE(mtc->ras) = 0;
437 SUBTLV_LEN(mtc->ras) = 0;
438 mtc->ras.value = 0;
439}
440
441static void
442set_circuitparams_av_delay (struct mpls_te_circuit *mtc, u_int32_t delay, u_char anormal)
443{
444 u_int32_t tmp;
445 /* Note that TLV-length field is the size of array. */
446 SUBTLV_TYPE(mtc->av_delay) = TE_SUBTLV_AV_DELAY;
447 SUBTLV_LEN(mtc->av_delay) = SUBTLV_DEF_SIZE;
448 tmp = delay & TE_EXT_MASK;
449 if (anormal)
450 tmp |= TE_EXT_ANORMAL;
451 mtc->av_delay.value = htonl(tmp);
452 return;
453}
454
455static void
456set_circuitparams_mm_delay (struct mpls_te_circuit *mtc, u_int32_t low, u_int32_t high, u_char anormal)
457{
458 u_int32_t tmp;
459 /* Note that TLV-length field is the size of array. */
460 SUBTLV_TYPE(mtc->mm_delay) = TE_SUBTLV_MM_DELAY;
461 SUBTLV_LEN(mtc->mm_delay) = TE_SUBTLV_MM_DELAY_SIZE;
462 tmp = low & TE_EXT_MASK;
463 if (anormal)
464 tmp |= TE_EXT_ANORMAL;
465 mtc->mm_delay.low = htonl(tmp);
466 mtc->mm_delay.high = htonl(high);
467 return;
468}
469
470static void
471set_circuitparams_delay_var (struct mpls_te_circuit *mtc, u_int32_t jitter)
472{
473 /* Note that TLV-length field is the size of array. */
474 SUBTLV_TYPE(mtc->delay_var) = TE_SUBTLV_DELAY_VAR;
475 SUBTLV_LEN(mtc->delay_var) = SUBTLV_DEF_SIZE;
476 mtc->delay_var.value = htonl(jitter & TE_EXT_MASK);
477 return;
478}
479
480static void
481set_circuitparams_pkt_loss (struct mpls_te_circuit *mtc, u_int32_t loss, u_char anormal)
482{
483 u_int32_t tmp;
484 /* Note that TLV-length field is the size of array. */
485 SUBTLV_TYPE(mtc->pkt_loss) = TE_SUBTLV_PKT_LOSS;
486 SUBTLV_LEN(mtc->pkt_loss) = SUBTLV_DEF_SIZE;
487 tmp = loss & TE_EXT_MASK;
488 if (anormal)
489 tmp |= TE_EXT_ANORMAL;
490 mtc->pkt_loss.value = htonl(tmp);
491 return;
492}
493
494static void
495set_circuitparams_res_bw (struct mpls_te_circuit *mtc, float fp)
496{
497 /* Note that TLV-length field is the size of array. */
498 SUBTLV_TYPE(mtc->res_bw) = TE_SUBTLV_RES_BW;
499 SUBTLV_LEN(mtc->res_bw) = SUBTLV_DEF_SIZE;
500 mtc->res_bw.value = htonf(fp);
501 return;
502}
503
504static void
505set_circuitparams_ava_bw (struct mpls_te_circuit *mtc, float fp)
506{
507 /* Note that TLV-length field is the size of array. */
508 SUBTLV_TYPE(mtc->ava_bw) = TE_SUBTLV_AVA_BW;
509 SUBTLV_LEN(mtc->ava_bw) = SUBTLV_DEF_SIZE;
510 mtc->ava_bw.value = htonf(fp);
511 return;
512}
513
514static void
515set_circuitparams_use_bw (struct mpls_te_circuit *mtc, float fp)
516{
517 /* Note that TLV-length field is the size of array. */
518 SUBTLV_TYPE(mtc->use_bw) = TE_SUBTLV_USE_BW;
519 SUBTLV_LEN(mtc->use_bw) = SUBTLV_DEF_SIZE;
520 mtc->use_bw.value = htonf(fp);
521 return;
522}
523
524/* Main initialization / update function of the MPLS TE Circuit context */
525/* Call when interface TE Link parameters are modified */
526void
527isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp)
528{
529 int i;
530 struct prefix_ipv4 *addr;
531 struct mpls_te_circuit *mtc;
532
533 /* Sanity Check */
534 if ((circuit == NULL) || (ifp == NULL))
535 return;
536
537 zlog_info ("MPLS-TE: Initialize circuit parameters for interface %s", ifp->name);
538
539 /* Check if MPLS TE Circuit context has not been already created */
540 if (circuit->mtc == NULL)
541 circuit->mtc = mpls_te_circuit_new();
542
543 mtc = circuit->mtc;
544
545 /* Fulfil MTC TLV from ifp TE Link parameters */
546 if (HAS_LINK_PARAMS(ifp))
547 {
548 mtc->status = enable;
549 /* STD_TE metrics */
550 if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP))
551 set_circuitparams_admin_grp (mtc, ifp->link_params->admin_grp);
552 else
553 SUBTLV_TYPE(mtc->admin_grp) = 0;
554
555 /* If not already set, register local IP addr from ip_addr list if it exists */
556 if (SUBTLV_TYPE(mtc->local_ipaddr) == 0)
557 {
558 if (circuit->ip_addrs != NULL && listcount(circuit->ip_addrs) != 0)
559 {
560 addr = (struct prefix_ipv4 *)listgetdata ((struct listnode *)listhead (circuit->ip_addrs));
561 set_circuitparams_local_ipaddr (mtc, addr->prefix);
562 }
563 }
564
565 /* If not already set, try to determine Remote IP addr if circuit is P2P */
566 if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) && (circuit->circ_type == CIRCUIT_T_P2P))
567 {
568 struct isis_adjacency *adj = circuit->u.p2p.neighbor;
569 if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
570 {
571 struct in_addr *ip_addr;
572 ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
573 set_circuitparams_rmt_ipaddr (mtc, *ip_addr);
574 }
575 }
576
577 if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW))
578 set_circuitparams_max_bw (mtc, ifp->link_params->max_bw);
579 else
580 SUBTLV_TYPE(mtc->max_bw) = 0;
581
582 if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW))
583 set_circuitparams_max_rsv_bw (mtc, ifp->link_params->max_rsv_bw);
584 else
585 SUBTLV_TYPE(mtc->max_rsv_bw) = 0;
586
587 if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW))
588 for (i = 0; i < MAX_CLASS_TYPE; i++)
589 set_circuitparams_unrsv_bw (mtc, i, ifp->link_params->unrsv_bw[i]);
590 else
591 SUBTLV_TYPE(mtc->unrsv_bw) = 0;
592
593 if (IS_PARAM_SET(ifp->link_params, LP_TE))
594 set_circuitparams_te_metric(mtc, ifp->link_params->te_metric);
595 else
596 SUBTLV_TYPE(mtc->te_metric) = 0;
597
598 /* TE metric Extensions */
599 if (IS_PARAM_SET(ifp->link_params, LP_DELAY))
600 set_circuitparams_av_delay(mtc, ifp->link_params->av_delay, 0);
601 else
602 SUBTLV_TYPE(mtc->av_delay) = 0;
603
604 if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY))
605 set_circuitparams_mm_delay(mtc, ifp->link_params->min_delay, ifp->link_params->max_delay, 0);
606 else
607 SUBTLV_TYPE(mtc->mm_delay) = 0;
608
609 if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR))
610 set_circuitparams_delay_var(mtc, ifp->link_params->delay_var);
611 else
612 SUBTLV_TYPE(mtc->delay_var) = 0;
613
614 if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS))
615 set_circuitparams_pkt_loss(mtc, ifp->link_params->pkt_loss, 0);
616 else
617 SUBTLV_TYPE(mtc->pkt_loss) = 0;
618
619 if (IS_PARAM_SET(ifp->link_params, LP_RES_BW))
620 set_circuitparams_res_bw(mtc, ifp->link_params->res_bw);
621 else
622 SUBTLV_TYPE(mtc->res_bw) = 0;
623
624 if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW))
625 set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw);
626 else
627 SUBTLV_TYPE(mtc->ava_bw) = 0;
628
629 if (IS_PARAM_SET(ifp->link_params, LP_USE_BW))
630 set_circuitparams_use_bw(mtc, ifp->link_params->use_bw);
631 else
632 SUBTLV_TYPE(mtc->use_bw) = 0;
633
634 /* INTER_AS */
635 if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS))
636 set_circuitparams_inter_as(mtc, ifp->link_params->rmt_ip, ifp->link_params->rmt_as);
637 else
638 /* reset inter-as TE params */
639 unset_circuitparams_inter_as (mtc);
640
641 /* Compute total length of SUB TLVs */
642 mtc->length = subtlvs_len(mtc);
643
644 }
645 else
646 mtc->status = disable;
647
648 /* Finally Update LSP */
649#if 0
650 if (IS_MPLS_TE(isisMplsTE) && circuit->area)
651 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
652#endif
653 return;
654}
655
656void
657isis_mpls_te_update (struct interface *ifp)
658{
659 struct isis_circuit *circuit;
660
661 /* Sanity Check */
662 if (ifp == NULL)
663 return;
664
665 /* Get circuit context from interface */
666 if ((circuit = circuit_scan_by_ifp(ifp)) == NULL)
667 return;
668
669 /* Update TE TLVs ... */
670 isis_link_params_update(circuit, ifp);
671
672 /* ... and LSP */
673 if (IS_MPLS_TE(isisMplsTE) && circuit->area)
674 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
675
676 return;
677}
678
679/*------------------------------------------------------------------------*
680 * Followings are vty session control functions.
681 *------------------------------------------------------------------------*/
682
683static u_char
684show_vty_subtlv_admin_grp (struct vty *vty, struct te_subtlv_admin_grp *tlv)
685{
686
687 if (vty != NULL)
688 vty_out (vty, " Administrative Group: 0x%x%s",
689 (u_int32_t) ntohl (tlv->value), VTY_NEWLINE);
690 else
691 zlog_debug (" Administrative Group: 0x%x",
692 (u_int32_t) ntohl (tlv->value));
693
694 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
695}
696
697static u_char
698show_vty_subtlv_llri (struct vty *vty, struct te_subtlv_llri *tlv)
699{
700 if (vty != NULL)
701 {
702 vty_out (vty, " Link Local ID: %d%s", (u_int32_t) ntohl (tlv->local),
703 VTY_NEWLINE);
704 vty_out (vty, " Link Remote ID: %d%s", (u_int32_t) ntohl (tlv->remote),
705 VTY_NEWLINE);
706 }
707 else
708 {
709 zlog_debug (" Link Local ID: %d", (u_int32_t) ntohl (tlv->local));
710 zlog_debug (" Link Remote ID: %d", (u_int32_t) ntohl (tlv->remote));
711 }
712
713 return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE);
714}
715
716static u_char
717show_vty_subtlv_local_ipaddr (struct vty *vty, struct te_subtlv_local_ipaddr *tlv)
718{
719 if (vty != NULL)
720 vty_out (vty, " Local Interface IP Address(es): %s%s", inet_ntoa (tlv->value), VTY_NEWLINE);
721 else
722 zlog_debug (" Local Interface IP Address(es): %s", inet_ntoa (tlv->value));
723
724 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
725}
726
727static u_char
728show_vty_subtlv_rmt_ipaddr (struct vty *vty, struct te_subtlv_rmt_ipaddr *tlv)
729{
730 if (vty != NULL)
731 vty_out (vty, " Remote Interface IP Address(es): %s%s", inet_ntoa (tlv->value), VTY_NEWLINE);
732 else
733 zlog_debug (" Remote Interface IP Address(es): %s", inet_ntoa (tlv->value));
734
735 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
736}
737
738static u_char
739show_vty_subtlv_max_bw (struct vty *vty, struct te_subtlv_max_bw *tlv)
740{
741 float fval;
742
743 fval = ntohf (tlv->value);
744
745 if (vty != NULL)
746 vty_out (vty, " Maximum Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
747 else
748 zlog_debug (" Maximum Bandwidth: %g (Bytes/sec)", fval);
749
750 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
751}
752
753static u_char
754show_vty_subtlv_max_rsv_bw (struct vty *vty, struct te_subtlv_max_rsv_bw *tlv)
755{
756 float fval;
757
758 fval = ntohf (tlv->value);
759
760 if (vty != NULL)
761 vty_out (vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)%s", fval,
762 VTY_NEWLINE);
763 else
764 zlog_debug (" Maximum Reservable Bandwidth: %g (Bytes/sec)", fval);
765
766 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
767}
768
769static u_char
770show_vty_subtlv_unrsv_bw (struct vty *vty, struct te_subtlv_unrsv_bw *tlv)
771{
772 float fval1, fval2;
773 int i;
774
775 if (vty != NULL)
776 vty_out (vty, " Unreserved Bandwidth:%s",VTY_NEWLINE);
777 else
778 zlog_debug (" Unreserved Bandwidth:");
779
780 for (i = 0; i < MAX_CLASS_TYPE; i+=2)
781 {
782 fval1 = ntohf (tlv->value[i]);
783 fval2 = ntohf (tlv->value[i+1]);
784 if (vty != NULL)
785 vty_out (vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s", i, fval1, i+1, fval2, VTY_NEWLINE);
786 else
787 zlog_debug (" [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)", i, fval1, i+1, fval2);
788 }
789
790 return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
791}
792
793static u_char
794show_vty_subtlv_te_metric (struct vty *vty, struct te_subtlv_te_metric *tlv)
795{
796 u_int32_t te_metric;
797
798 te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16;
799 if (vty != NULL)
800 vty_out (vty, " Traffic Engineering Metric: %u%s", te_metric, VTY_NEWLINE);
801 else
802 zlog_debug (" Traffic Engineering Metric: %u", te_metric);
803
804 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
805}
806
807static u_char
808show_vty_subtlv_ras (struct vty *vty, struct te_subtlv_ras *tlv)
809{
810 if (vty != NULL)
811 vty_out (vty, " Inter-AS TE Remote AS number: %u%s", ntohl (tlv->value), VTY_NEWLINE);
812 else
813 zlog_debug (" Inter-AS TE Remote AS number: %u", ntohl (tlv->value));
814
815 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
816}
817
818static u_char
819show_vty_subtlv_rip (struct vty *vty, struct te_subtlv_rip *tlv)
820{
821 if (vty != NULL)
822 vty_out (vty, " Inter-AS TE Remote ASBR IP address: %s%s", inet_ntoa (tlv->value), VTY_NEWLINE);
823 else
824 zlog_debug (" Inter-AS TE Remote ASBR IP address: %s", inet_ntoa (tlv->value));
825
826 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
827}
828
829static u_char
830show_vty_subtlv_av_delay (struct vty *vty, struct te_subtlv_av_delay *tlv)
831{
832 u_int32_t delay;
833 u_int32_t A;
834
835 delay = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK;
836 A = (u_int32_t) ntohl (tlv->value) & TE_EXT_ANORMAL;
837
838 if (vty != NULL)
839 vty_out (vty, " %s Average Link Delay: %d (micro-sec)%s", A ? "Anomalous" : "Normal", delay, VTY_NEWLINE);
840 else
841 zlog_debug (" %s Average Link Delay: %d (micro-sec)", A ? "Anomalous" : "Normal", delay);
842
843 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
844}
845
846static u_char
847show_vty_subtlv_mm_delay (struct vty *vty, struct te_subtlv_mm_delay *tlv)
848{
849 u_int32_t low, high;
850 u_int32_t A;
851
852 low = (u_int32_t) ntohl (tlv->low) & TE_EXT_MASK;
853 A = (u_int32_t) ntohl (tlv->low) & TE_EXT_ANORMAL;
854 high = (u_int32_t) ntohl (tlv->high) & TE_EXT_MASK;
855
856 if (vty != NULL)
857 vty_out (vty, " %s Min/Max Link Delay: %d / %d (micro-sec)%s", A ? "Anomalous" : "Normal", low, high, VTY_NEWLINE);
858 else
859 zlog_debug (" %s Min/Max Link Delay: %d / %d (micro-sec)", A ? "Anomalous" : "Normal", low, high);
860
861 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
862}
863
864static u_char
865show_vty_subtlv_delay_var (struct vty *vty, struct te_subtlv_delay_var *tlv)
866{
867 u_int32_t jitter;
868
869 jitter = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK;
870
871 if (vty != NULL)
872 vty_out (vty, " Delay Variation: %d (micro-sec)%s", jitter, VTY_NEWLINE);
873 else
874 zlog_debug (" Delay Variation: %d (micro-sec)", jitter);
875
876 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
877}
878
879static u_char
880show_vty_subtlv_pkt_loss (struct vty *vty, struct te_subtlv_pkt_loss *tlv)
881{
882 u_int32_t loss;
883 u_int32_t A;
884 float fval;
885
886 loss = (u_int32_t) ntohl (tlv->value) & TE_EXT_MASK;
887 fval = (float) (loss * LOSS_PRECISION);
888 A = (u_int32_t) ntohl (tlv->value) & TE_EXT_ANORMAL;
889
890 if (vty != NULL)
891 vty_out (vty, " %s Link Packet Loss: %g (%%)%s", A ? "Anomalous" : "Normal", fval, VTY_NEWLINE);
892 else
893 zlog_debug (" %s Link Packet Loss: %g (%%)", A ? "Anomalous" : "Normal", fval);
894
895 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
896}
897
898static u_char
899show_vty_subtlv_res_bw (struct vty *vty, struct te_subtlv_res_bw *tlv)
900{
901 float fval;
902
903 fval = ntohf(tlv->value);
904
905 if (vty != NULL)
906 vty_out (vty, " Unidirectional Residual Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
907 else
908 zlog_debug (" Unidirectional Residual Bandwidth: %g (Bytes/sec)", fval);
909
910 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
911}
912
913static u_char
914show_vty_subtlv_ava_bw (struct vty *vty, struct te_subtlv_ava_bw *tlv)
915{
916 float fval;
917
918 fval = ntohf (tlv->value);
919
920 if (vty != NULL)
921 vty_out (vty, " Unidirectional Available Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
922 else
923 zlog_debug (" Unidirectional Available Bandwidth: %g (Bytes/sec)", fval);
924
925 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
926}
927
928static u_char
929show_vty_subtlv_use_bw (struct vty *vty, struct te_subtlv_use_bw *tlv)
930{
931 float fval;
932
933 fval = ntohf (tlv->value);
934
935 if (vty != NULL)
936 vty_out (vty, " Unidirectional Utilized Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
937 else
938 zlog_debug (" Unidirectional Utilized Bandwidth: %g (Bytes/sec)", fval);
939
940 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
941}
942
943static u_char
944show_vty_unknown_tlv (struct vty *vty, struct subtlv_header *tlvh)
945{
946 int i, rtn = 1;
947 u_char *v = (u_char *)tlvh;
948
949 if (vty != NULL)
950 {
951 if (tlvh->length != 0)
952 {
953 vty_out (vty, " Unknown TLV: [type(%#.2x), length(%#.2x)]%s",
954 tlvh->type, tlvh->length, VTY_NEWLINE);
955 vty_out(vty, " Dump: [00]");
956 rtn = 1; /* initialize end of line counter */
957 for (i = 0; i < tlvh->length; i++)
958 {
959 vty_out (vty, " %#.2x", v[i]);
960 if (rtn == 8)
961 {
962 vty_out (vty, "%s [%.2x]", VTY_NEWLINE, i + 1);
963 rtn = 1;
964 }
965 else
966 rtn++;
967 }
968 vty_out (vty, "%s", VTY_NEWLINE);
969 }
970 else
971 vty_out (vty, " Unknown TLV: [type(%#.2x), length(%#.2x)]%s",
972 tlvh->type, tlvh->length, VTY_NEWLINE);
973 }
974 else
975 {
976 zlog_debug (" Unknown TLV: [type(%#.2x), length(%#.2x)]",
977 tlvh->type, tlvh->length);
978 }
979
980 return SUBTLV_SIZE(tlvh);
981}
982
983/* Main Show function */
984void
985mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te)
986{
987 struct subtlv_header *tlvh, *next;
988 u_int16_t sum = 0;
989
990 zlog_debug ("ISIS MPLS-TE: Show database TE detail");
991
992 if (te->sub_tlvs == NULL)
993 return;
994
995 tlvh = (struct subtlv_header *)te->sub_tlvs;
996
997 for (; sum < te->sub_tlvs_length; tlvh = (next ? next : SUBTLV_HDR_NEXT (tlvh)))
998 {
999 next = NULL;
1000
1001 switch (tlvh->type)
1002 {
1003 case TE_SUBTLV_ADMIN_GRP:
1004 sum += show_vty_subtlv_admin_grp (vty, (struct te_subtlv_admin_grp *)tlvh);
1005 break;
1006 case TE_SUBTLV_LLRI:
1007 sum += show_vty_subtlv_llri (vty, (struct te_subtlv_llri *)tlvh);
1008 break;
1009 case TE_SUBTLV_LOCAL_IPADDR:
1010 sum += show_vty_subtlv_local_ipaddr (vty, (struct te_subtlv_local_ipaddr *)tlvh);
1011 break;
1012 case TE_SUBTLV_RMT_IPADDR:
1013 sum += show_vty_subtlv_rmt_ipaddr (vty, (struct te_subtlv_rmt_ipaddr *)tlvh);
1014 break;
1015 case TE_SUBTLV_MAX_BW:
1016 sum += show_vty_subtlv_max_bw (vty, (struct te_subtlv_max_bw *)tlvh);
1017 break;
1018 case TE_SUBTLV_MAX_RSV_BW:
1019 sum += show_vty_subtlv_max_rsv_bw (vty, (struct te_subtlv_max_rsv_bw *)tlvh);
1020 break;
1021 case TE_SUBTLV_UNRSV_BW:
1022 sum += show_vty_subtlv_unrsv_bw (vty, (struct te_subtlv_unrsv_bw *)tlvh);
1023 break;
1024 case TE_SUBTLV_TE_METRIC:
1025 sum += show_vty_subtlv_te_metric (vty, (struct te_subtlv_te_metric *)tlvh);
1026 break;
1027 case TE_SUBTLV_RAS:
1028 sum += show_vty_subtlv_ras (vty, (struct te_subtlv_ras *)tlvh);
1029 break;
1030 case TE_SUBTLV_RIP:
1031 sum += show_vty_subtlv_rip (vty, (struct te_subtlv_rip *)tlvh);
1032 break;
1033 case TE_SUBTLV_AV_DELAY:
1034 sum += show_vty_subtlv_av_delay (vty, (struct te_subtlv_av_delay *)tlvh);
1035 break;
1036 case TE_SUBTLV_MM_DELAY:
1037 sum += show_vty_subtlv_mm_delay (vty, (struct te_subtlv_mm_delay *)tlvh);
1038 break;
1039 case TE_SUBTLV_DELAY_VAR:
1040 sum += show_vty_subtlv_delay_var (vty, (struct te_subtlv_delay_var *)tlvh);
1041 break;
1042 case TE_SUBTLV_PKT_LOSS:
1043 sum += show_vty_subtlv_pkt_loss (vty, (struct te_subtlv_pkt_loss *)tlvh);
1044 break;
1045 case TE_SUBTLV_RES_BW:
1046 sum += show_vty_subtlv_res_bw (vty, (struct te_subtlv_res_bw *)tlvh);
1047 break;
1048 case TE_SUBTLV_AVA_BW:
1049 sum += show_vty_subtlv_ava_bw (vty, (struct te_subtlv_ava_bw *)tlvh);
1050 break;
1051 case TE_SUBTLV_USE_BW:
1052 sum += show_vty_subtlv_use_bw (vty, (struct te_subtlv_use_bw *)tlvh);
1053 break;
1054 default:
1055 sum += show_vty_unknown_tlv (vty, tlvh);
1056 break;
1057 }
1058 }
1059 return;
1060}
1061
1062/* Specific MPLS TE router parameters write function */
1063void
1064isis_mpls_te_config_write_router (struct vty *vty)
1065{
1066
1067 zlog_debug ("ISIS MPLS-TE: Write ISIS router configuration");
1068
1069 if (IS_MPLS_TE(isisMplsTE))
1070 {
1071 vty_out (vty, " mpls-te on%s", VTY_NEWLINE);
1072 vty_out (vty, " mpls-te router-address %s%s",
1073 inet_ntoa (isisMplsTE.router_id), VTY_NEWLINE);
1074 }
1075
1076 return;
1077}
1078
1079
1080/*------------------------------------------------------------------------*
1081 * Followings are vty command functions.
1082 *------------------------------------------------------------------------*/
1083
1084DEFUN (isis_mpls_te_on,
1085 isis_mpls_te_on_cmd,
1086 "mpls-te on",
1087 MPLS_TE_STR
1088 "Enable MPLS-TE functionality\n")
1089{
1090 struct listnode *node;
1091 struct isis_circuit *circuit;
1092
1093 if (IS_MPLS_TE(isisMplsTE))
1094 return CMD_SUCCESS;
1095
1096 if (IS_DEBUG_ISIS(DEBUG_TE))
1097 zlog_debug ("ISIS MPLS-TE: OFF -> ON");
1098
1099 isisMplsTE.status = enable;
1100
1101 /*
1102 * Following code is intended to handle two cases;
1103 *
1104 * 1) MPLS-TE was disabled at startup time, but now become enabled.
1105 * In this case, we must enable MPLS-TE Circuit regarding interface MPLS_TE flag
1106 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1107 */
1108 for (ALL_LIST_ELEMENTS_RO (isisMplsTE.cir_list, node, circuit))
1109 {
1110 if (circuit->mtc == NULL || IS_FLOOD_AS (circuit->mtc->type))
1111 continue;
1112
1113 if ((circuit->mtc->status == disable)
1114 && HAS_LINK_PARAMS(circuit->interface))
1115 circuit->mtc->status = enable;
1116 else
1117 continue;
1118
1119 /* Reoriginate STD_TE & GMPLS circuits */
1120 if (circuit->area)
1121 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
1122 }
1123
1124 return CMD_SUCCESS;
1125}
1126
1127DEFUN (no_isis_mpls_te_on,
1128 no_isis_mpls_te_on_cmd,
1129 "no mpls-te",
1130 NO_STR
1131 "Disable the MPLS-TE functionality\n")
1132{
1133 struct listnode *node;
1134 struct isis_circuit *circuit;
1135
1136 if (isisMplsTE.status == disable)
1137 return CMD_SUCCESS;
1138
1139 if (IS_DEBUG_ISIS(DEBUG_TE))
1140 zlog_debug ("ISIS MPLS-TE: ON -> OFF");
1141
1142 isisMplsTE.status = disable;
1143
1144 /* Flush LSP if circuit engage */
1145 for (ALL_LIST_ELEMENTS_RO (isisMplsTE.cir_list, node, circuit))
1146 {
1147 if (circuit->mtc == NULL || (circuit->mtc->status == disable))
1148 continue;
1149
1150 /* disable MPLS_TE Circuit */
1151 circuit->mtc->status = disable;
1152
1153 /* Re-originate circuit without STD_TE & GMPLS parameters */
1154 if (circuit->area)
1155 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
1156 }
1157
1158 return CMD_SUCCESS;
1159}
1160
1161DEFUN (isis_mpls_te_router_addr,
1162 isis_mpls_te_router_addr_cmd,
1163 "mpls-te router-address A.B.C.D",
1164 MPLS_TE_STR
1165 "Stable IP address of the advertising router\n"
1166 "MPLS-TE router address in IPv4 address format\n")
1167{
1168 struct in_addr value;
1169 struct listnode *node;
1170 struct isis_area *area;
1171
1172 if (! inet_aton (argv[0], &value))
1173 {
1174 vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
1175 return CMD_WARNING;
1176 }
1177
1178 isisMplsTE.router_id.s_addr = value.s_addr;
1179
1180 if (isisMplsTE.status == disable)
1181 return CMD_SUCCESS;
1182
1183 /* Update main Router ID in isis global structure */
1184 isis->router_id = value.s_addr;
1185 /* And re-schedule LSP update */
1186 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
1187 if (listcount (area->area_addrs) > 0)
1188 lsp_regenerate_schedule (area, area->is_type, 0);
1189
1190 return CMD_SUCCESS;
1191}
1192
1193DEFUN (isis_mpls_te_inter_as,
1194 isis_mpls_te_inter_as_cmd,
1195 "mpls-te inter-as (level-1|level-1-2|level-2-only)",
1196 MPLS_TE_STR
1197 "Configure MPLS-TE Inter-AS support\n"
1198 "AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n"
1199 "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n"
1200 "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
1201{
1202 vty_out (vty, "Not yet supported%s", VTY_NEWLINE);
1203 return CMD_SUCCESS;
1204}
1205
1206DEFUN (no_isis_mpls_te_inter_as,
1207 no_isis_mpls_te_inter_as_cmd,
1208 "no mpls-te inter-as",
1209 NO_STR
1210 "Disable the MPLS-TE functionality\n"
1211 "Disable MPLS-TE Inter-AS support\n")
1212{
1213
1214 vty_out (vty, "Not yet supported%s", VTY_NEWLINE);
1215 return CMD_SUCCESS;
1216}
1217
1218DEFUN (show_isis_mpls_te_router,
1219 show_isis_mpls_te_router_cmd,
1220 "show isis mpls-te router",
1221 SHOW_STR
1222 ISIS_STR
1223 MPLS_TE_STR
1224 "Router information\n")
1225{
1226 if (IS_MPLS_TE(isisMplsTE))
1227 {
1228 vty_out (vty, "--- MPLS-TE router parameters ---%s", VTY_NEWLINE);
1229
1230 if (vty != NULL)
1231 {
1232 if (ntohs (isisMplsTE.router_id.s_addr) != 0)
1233 vty_out (vty, " Router-Address: %s%s", inet_ntoa (isisMplsTE.router_id), VTY_NEWLINE);
1234 else
1235 vty_out (vty, " N/A%s", VTY_NEWLINE);
1236 }
1237 }
1238 else
1239 vty_out (vty, " MPLS-TE is disable on this router%s", VTY_NEWLINE);
1240
1241 return CMD_SUCCESS;
1242}
1243
1244static void
1245show_mpls_te_sub (struct vty *vty, struct interface *ifp)
1246{
1247 struct mpls_te_circuit *mtc;
1248
1249 if ((IS_MPLS_TE(isisMplsTE))
1250 && ((mtc = lookup_mpls_params_by_ifp (ifp)) != NULL))
1251 {
1252 /* Continue only if interface is not passive or support Inter-AS TEv2 */
1253 if (mtc->status != enable)
1254 {
1255 if (IS_INTER_AS(mtc->type))
1256 {
1257 vty_out (vty, "-- Inter-AS TEv2 link parameters for %s --%s",
1258 ifp->name, VTY_NEWLINE);
1259 }
1260 else
1261 {
1262 /* MPLS-TE is not activate on this interface */
1263 /* or this interface is passive and Inter-AS TEv2 is not activate */
1264 vty_out (vty, " %s: MPLS-TE is disabled on this interface%s",
1265 ifp->name, VTY_NEWLINE);
1266 return;
1267 }
1268 }
1269 else
1270 {
1271 vty_out (vty, "-- MPLS-TE link parameters for %s --%s",
1272 ifp->name, VTY_NEWLINE);
1273 }
1274
1275 show_vty_subtlv_admin_grp (vty, &mtc->admin_grp);
1276
1277 if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
1278 show_vty_subtlv_local_ipaddr (vty, &mtc->local_ipaddr);
1279 if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
1280 show_vty_subtlv_rmt_ipaddr (vty, &mtc->rmt_ipaddr);
1281
1282 show_vty_subtlv_max_bw (vty, &mtc->max_bw);
1283 show_vty_subtlv_max_rsv_bw (vty, &mtc->max_rsv_bw);
1284 show_vty_subtlv_unrsv_bw (vty, &mtc->unrsv_bw);
1285 show_vty_subtlv_te_metric (vty, &mtc->te_metric);
1286
1287 if (IS_INTER_AS(mtc->type))
1288 {
1289 if (SUBTLV_TYPE(mtc->ras) != 0)
1290 show_vty_subtlv_ras (vty, &mtc->ras);
1291 if (SUBTLV_TYPE(mtc->rip) != 0)
1292 show_vty_subtlv_rip (vty, &mtc->rip);
1293 }
1294
1295 show_vty_subtlv_av_delay (vty, &mtc->av_delay);
1296 show_vty_subtlv_mm_delay (vty, &mtc->mm_delay);
1297 show_vty_subtlv_delay_var (vty, &mtc->delay_var);
1298 show_vty_subtlv_pkt_loss (vty, &mtc->pkt_loss);
1299 show_vty_subtlv_res_bw (vty, &mtc->res_bw);
1300 show_vty_subtlv_ava_bw (vty, &mtc->ava_bw);
1301 show_vty_subtlv_use_bw (vty, &mtc->use_bw);
1302 vty_out (vty, "---------------%s%s", VTY_NEWLINE, VTY_NEWLINE);
1303 }
1304 else
1305 {
1306 vty_out (vty, " %s: MPLS-TE is disabled on this interface%s",
1307 ifp->name, VTY_NEWLINE);
1308 }
1309
1310 return;
1311}
1312
1313DEFUN (show_isis_mpls_te_interface,
1314 show_isis_mpls_te_interface_cmd,
1315 "show isis mpls-te interface [INTERFACE]",
1316 SHOW_STR
1317 ISIS_STR
1318 MPLS_TE_STR
1319 "Interface information\n"
1320 "Interface name\n")
1321{
1322 struct interface *ifp;
1323 struct listnode *node;
1324
1325 /* Show All Interfaces. */
1326 if (argc == 0)
1327 {
1328 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
1329 show_mpls_te_sub (vty, ifp);
1330 }
1331 /* Interface name is specified. */
1332 else
1333 {
1334 if ((ifp = if_lookup_by_name (argv[0])) == NULL)
1335 vty_out (vty, "No such interface name%s", VTY_NEWLINE);
1336 else
1337 show_mpls_te_sub (vty, ifp);
1338 }
1339
1340 return CMD_SUCCESS;
1341}
1342
1343/* Initialize MPLS_TE */
1344void
1345isis_mpls_te_init (void)
1346{
1347
1348 zlog_debug("ISIS MPLS-TE: Initialize");
1349
1350 /* Initialize MPLS_TE structure */
1351 isisMplsTE.status = disable;
1352 isisMplsTE.level = 0;
1353 isisMplsTE.inter_as = off;
1354 isisMplsTE.interas_areaid.s_addr = 0;
1355 isisMplsTE.cir_list = list_new();
1356 isisMplsTE.router_id.s_addr = 0;
1357
1358 /* Register new VTY commands */
1359 install_element (VIEW_NODE, &show_isis_mpls_te_router_cmd);
1360 install_element (VIEW_NODE, &show_isis_mpls_te_interface_cmd);
1361 install_element (ENABLE_NODE, &show_isis_mpls_te_router_cmd);
1362 install_element (ENABLE_NODE, &show_isis_mpls_te_interface_cmd);
1363
1364 install_element (ISIS_NODE, &isis_mpls_te_on_cmd);
1365 install_element (ISIS_NODE, &no_isis_mpls_te_on_cmd);
1366 install_element (ISIS_NODE, &isis_mpls_te_router_addr_cmd);
1367 install_element (ISIS_NODE, &isis_mpls_te_inter_as_cmd);
1368 install_element (ISIS_NODE, &no_isis_mpls_te_inter_as_cmd);
1369
1370 return;
1371}
1372