2 * IS-IS Rout(e)ing protocol - isis_te.c
4 * This is an implementation of RFC5305 & RFC 7810
6 * Copyright (C) 2014 Orange Labs
7 * http://www.orange.com
9 * This file is part of GNU Zebra.
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
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.
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
43 #include "sockunion.h"
46 #include "isisd/dict.h"
47 #include "isisd/isis_constants.h"
48 #include "isisd/isis_common.h"
49 #include "isisd/isis_flags.h"
50 #include "isisd/isis_circuit.h"
51 #include "isisd/isisd.h"
52 #include "isisd/isis_tlv.h"
53 #include "isisd/isis_lsp.h"
54 #include "isisd/isis_pdu.h"
55 #include "isisd/isis_dynhn.h"
56 #include "isisd/isis_misc.h"
57 #include "isisd/isis_csm.h"
58 #include "isisd/isis_adjacency.h"
59 #include "isisd/isis_spf.h"
60 #include "isisd/isis_te.h"
62 /* Global varial for MPLS TE management */
63 struct isis_mpls_te isisMplsTE
;
65 const char *mode2text
[] = {"Disable", "Area", "AS", "Emulate"};
67 /*------------------------------------------------------------------------*
68 * Followings are control functions for MPLS-TE parameters management.
69 *------------------------------------------------------------------------*/
71 /* Search MPLS TE Circuit context from Interface */
72 static struct mpls_te_circuit
*lookup_mpls_params_by_ifp(struct interface
*ifp
)
74 struct isis_circuit
*circuit
;
76 if ((circuit
= circuit_scan_by_ifp(ifp
)) == NULL
)
82 /* Create new MPLS TE Circuit context */
83 struct mpls_te_circuit
*mpls_te_circuit_new()
85 struct mpls_te_circuit
*mtc
;
87 zlog_debug("ISIS MPLS-TE: Create new MPLS TE Circuit context");
89 mtc
= XCALLOC(MTYPE_ISIS_MPLS_TE
, sizeof(struct mpls_te_circuit
));
94 mtc
->status
= disable
;
101 /* Copy SUB TLVs parameters into a buffer - No space verification are performed
103 /* Caller must verify before that there is enough free space in the buffer */
104 u_char
add_te_subtlvs(u_char
*buf
, struct mpls_te_circuit
*mtc
)
106 u_char size
, *tlvs
= buf
;
108 zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
112 "ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified");
116 /* Create buffer if not provided */
118 zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified");
122 /* TE_SUBTLV_ADMIN_GRP */
123 if (SUBTLV_TYPE(mtc
->admin_grp
) != 0) {
124 size
= SUBTLV_SIZE(&(mtc
->admin_grp
.header
));
125 memcpy(tlvs
, &(mtc
->admin_grp
), size
);
130 if (SUBTLV_TYPE(mtc
->llri
) != 0) {
131 size
= SUBTLV_SIZE(&(mtc
->llri
.header
));
132 memcpy(tlvs
, &(mtc
->llri
), size
);
136 /* TE_SUBTLV_LCLIF_IPADDR */
137 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0) {
138 size
= SUBTLV_SIZE(&(mtc
->local_ipaddr
.header
));
139 memcpy(tlvs
, &(mtc
->local_ipaddr
), size
);
143 /* TE_SUBTLV_RMTIF_IPADDR */
144 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0) {
145 size
= SUBTLV_SIZE(&(mtc
->rmt_ipaddr
.header
));
146 memcpy(tlvs
, &(mtc
->rmt_ipaddr
), size
);
150 /* TE_SUBTLV_MAX_BW */
151 if (SUBTLV_TYPE(mtc
->max_bw
) != 0) {
152 size
= SUBTLV_SIZE(&(mtc
->max_bw
.header
));
153 memcpy(tlvs
, &(mtc
->max_bw
), size
);
157 /* TE_SUBTLV_MAX_RSV_BW */
158 if (SUBTLV_TYPE(mtc
->max_rsv_bw
) != 0) {
159 size
= SUBTLV_SIZE(&(mtc
->max_rsv_bw
.header
));
160 memcpy(tlvs
, &(mtc
->max_rsv_bw
), size
);
164 /* TE_SUBTLV_UNRSV_BW */
165 if (SUBTLV_TYPE(mtc
->unrsv_bw
) != 0) {
166 size
= SUBTLV_SIZE(&(mtc
->unrsv_bw
.header
));
167 memcpy(tlvs
, &(mtc
->unrsv_bw
), size
);
171 /* TE_SUBTLV_TE_METRIC */
172 if (SUBTLV_TYPE(mtc
->te_metric
) != 0) {
173 size
= SUBTLV_SIZE(&(mtc
->te_metric
.header
));
174 memcpy(tlvs
, &(mtc
->te_metric
), size
);
178 /* TE_SUBTLV_AV_DELAY */
179 if (SUBTLV_TYPE(mtc
->av_delay
) != 0) {
180 size
= SUBTLV_SIZE(&(mtc
->av_delay
.header
));
181 memcpy(tlvs
, &(mtc
->av_delay
), size
);
185 /* TE_SUBTLV_MM_DELAY */
186 if (SUBTLV_TYPE(mtc
->mm_delay
) != 0) {
187 size
= SUBTLV_SIZE(&(mtc
->mm_delay
.header
));
188 memcpy(tlvs
, &(mtc
->mm_delay
), size
);
192 /* TE_SUBTLV_DELAY_VAR */
193 if (SUBTLV_TYPE(mtc
->delay_var
) != 0) {
194 size
= SUBTLV_SIZE(&(mtc
->delay_var
.header
));
195 memcpy(tlvs
, &(mtc
->delay_var
), size
);
199 /* TE_SUBTLV_PKT_LOSS */
200 if (SUBTLV_TYPE(mtc
->pkt_loss
) != 0) {
201 size
= SUBTLV_SIZE(&(mtc
->pkt_loss
.header
));
202 memcpy(tlvs
, &(mtc
->pkt_loss
), size
);
206 /* TE_SUBTLV_RES_BW */
207 if (SUBTLV_TYPE(mtc
->res_bw
) != 0) {
208 size
= SUBTLV_SIZE(&(mtc
->res_bw
.header
));
209 memcpy(tlvs
, &(mtc
->res_bw
), size
);
213 /* TE_SUBTLV_AVA_BW */
214 if (SUBTLV_TYPE(mtc
->ava_bw
) != 0) {
215 size
= SUBTLV_SIZE(&(mtc
->ava_bw
.header
));
216 memcpy(tlvs
, &(mtc
->ava_bw
), size
);
220 /* TE_SUBTLV_USE_BW */
221 if (SUBTLV_TYPE(mtc
->use_bw
) != 0) {
222 size
= SUBTLV_SIZE(&(mtc
->use_bw
.header
));
223 memcpy(tlvs
, &(mtc
->use_bw
), size
);
227 /* Update SubTLVs length */
228 mtc
->length
= subtlvs_len(mtc
);
230 zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc
->length
);
235 /* Compute total Sub-TLVs size */
236 u_char
subtlvs_len(struct mpls_te_circuit
*mtc
)
244 /* TE_SUBTLV_ADMIN_GRP */
245 if (SUBTLV_TYPE(mtc
->admin_grp
) != 0)
246 length
+= SUBTLV_SIZE(&(mtc
->admin_grp
.header
));
249 if (SUBTLV_TYPE(mtc
->llri
) != 0)
250 length
+= SUBTLV_SIZE(&mtc
->llri
.header
);
252 /* TE_SUBTLV_LCLIF_IPADDR */
253 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0)
254 length
+= SUBTLV_SIZE(&mtc
->local_ipaddr
.header
);
256 /* TE_SUBTLV_RMTIF_IPADDR */
257 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0)
258 length
+= SUBTLV_SIZE(&mtc
->rmt_ipaddr
.header
);
260 /* TE_SUBTLV_MAX_BW */
261 if (SUBTLV_TYPE(mtc
->max_bw
) != 0)
262 length
+= SUBTLV_SIZE(&mtc
->max_bw
.header
);
264 /* TE_SUBTLV_MAX_RSV_BW */
265 if (SUBTLV_TYPE(mtc
->max_rsv_bw
) != 0)
266 length
+= SUBTLV_SIZE(&mtc
->max_rsv_bw
.header
);
268 /* TE_SUBTLV_UNRSV_BW */
269 if (SUBTLV_TYPE(mtc
->unrsv_bw
) != 0)
270 length
+= SUBTLV_SIZE(&mtc
->unrsv_bw
.header
);
272 /* TE_SUBTLV_TE_METRIC */
273 if (SUBTLV_TYPE(mtc
->te_metric
) != 0)
274 length
+= SUBTLV_SIZE(&mtc
->te_metric
.header
);
276 /* TE_SUBTLV_AV_DELAY */
277 if (SUBTLV_TYPE(mtc
->av_delay
) != 0)
278 length
+= SUBTLV_SIZE(&mtc
->av_delay
.header
);
280 /* TE_SUBTLV_MM_DELAY */
281 if (SUBTLV_TYPE(mtc
->mm_delay
) != 0)
282 length
+= SUBTLV_SIZE(&mtc
->mm_delay
.header
);
284 /* TE_SUBTLV_DELAY_VAR */
285 if (SUBTLV_TYPE(mtc
->delay_var
) != 0)
286 length
+= SUBTLV_SIZE(&mtc
->delay_var
.header
);
288 /* TE_SUBTLV_PKT_LOSS */
289 if (SUBTLV_TYPE(mtc
->pkt_loss
) != 0)
290 length
+= SUBTLV_SIZE(&mtc
->pkt_loss
.header
);
292 /* TE_SUBTLV_RES_BW */
293 if (SUBTLV_TYPE(mtc
->res_bw
) != 0)
294 length
+= SUBTLV_SIZE(&mtc
->res_bw
.header
);
296 /* TE_SUBTLV_AVA_BW */
297 if (SUBTLV_TYPE(mtc
->ava_bw
) != 0)
298 length
+= SUBTLV_SIZE(&mtc
->ava_bw
.header
);
300 /* TE_SUBTLV_USE_BW */
301 if (SUBTLV_TYPE(mtc
->use_bw
) != 0)
302 length
+= SUBTLV_SIZE(&mtc
->use_bw
.header
);
304 /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */
305 if (length
> MAX_SUBTLV_SIZE
) {
310 mtc
->length
= (u_char
)length
;
315 /* Following are various functions to set MPLS TE parameters */
316 static void set_circuitparams_admin_grp(struct mpls_te_circuit
*mtc
,
319 SUBTLV_TYPE(mtc
->admin_grp
) = TE_SUBTLV_ADMIN_GRP
;
320 SUBTLV_LEN(mtc
->admin_grp
) = SUBTLV_DEF_SIZE
;
321 mtc
->admin_grp
.value
= htonl(admingrp
);
325 static void __attribute__((unused
))
326 set_circuitparams_llri(struct mpls_te_circuit
*mtc
, u_int32_t local
,
329 SUBTLV_TYPE(mtc
->llri
) = TE_SUBTLV_LLRI
;
330 SUBTLV_LEN(mtc
->llri
) = TE_SUBTLV_LLRI_SIZE
;
331 mtc
->llri
.local
= htonl(local
);
332 mtc
->llri
.remote
= htonl(remote
);
335 void set_circuitparams_local_ipaddr(struct mpls_te_circuit
*mtc
,
339 SUBTLV_TYPE(mtc
->local_ipaddr
) = TE_SUBTLV_LOCAL_IPADDR
;
340 SUBTLV_LEN(mtc
->local_ipaddr
) = SUBTLV_DEF_SIZE
;
341 mtc
->local_ipaddr
.value
.s_addr
= addr
.s_addr
;
345 void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit
*mtc
,
349 SUBTLV_TYPE(mtc
->rmt_ipaddr
) = TE_SUBTLV_RMT_IPADDR
;
350 SUBTLV_LEN(mtc
->rmt_ipaddr
) = SUBTLV_DEF_SIZE
;
351 mtc
->rmt_ipaddr
.value
.s_addr
= addr
.s_addr
;
355 static void set_circuitparams_max_bw(struct mpls_te_circuit
*mtc
, float fp
)
357 SUBTLV_TYPE(mtc
->max_bw
) = TE_SUBTLV_MAX_BW
;
358 SUBTLV_LEN(mtc
->max_bw
) = SUBTLV_DEF_SIZE
;
359 mtc
->max_bw
.value
= htonf(fp
);
363 static void set_circuitparams_max_rsv_bw(struct mpls_te_circuit
*mtc
, float fp
)
365 SUBTLV_TYPE(mtc
->max_rsv_bw
) = TE_SUBTLV_MAX_RSV_BW
;
366 SUBTLV_LEN(mtc
->max_rsv_bw
) = SUBTLV_DEF_SIZE
;
367 mtc
->max_rsv_bw
.value
= htonf(fp
);
371 static void set_circuitparams_unrsv_bw(struct mpls_te_circuit
*mtc
,
372 int priority
, float fp
)
374 /* Note that TLV-length field is the size of array. */
375 SUBTLV_TYPE(mtc
->unrsv_bw
) = TE_SUBTLV_UNRSV_BW
;
376 SUBTLV_LEN(mtc
->unrsv_bw
) = TE_SUBTLV_UNRSV_SIZE
;
377 mtc
->unrsv_bw
.value
[priority
] = htonf(fp
);
381 static void set_circuitparams_te_metric(struct mpls_te_circuit
*mtc
,
384 SUBTLV_TYPE(mtc
->te_metric
) = TE_SUBTLV_TE_METRIC
;
385 SUBTLV_LEN(mtc
->te_metric
) = TE_SUBTLV_TE_METRIC_SIZE
;
386 mtc
->te_metric
.value
[0] = (te_metric
>> 16) & 0xFF;
387 mtc
->te_metric
.value
[1] = (te_metric
>> 8) & 0xFF;
388 mtc
->te_metric
.value
[2] = te_metric
& 0xFF;
392 static void set_circuitparams_inter_as(struct mpls_te_circuit
*mtc
,
393 struct in_addr addr
, u_int32_t as
)
396 /* Set the Remote ASBR IP address and then the associated AS number */
397 SUBTLV_TYPE(mtc
->rip
) = TE_SUBTLV_RIP
;
398 SUBTLV_LEN(mtc
->rip
) = SUBTLV_DEF_SIZE
;
399 mtc
->rip
.value
.s_addr
= addr
.s_addr
;
401 SUBTLV_TYPE(mtc
->ras
) = TE_SUBTLV_RAS
;
402 SUBTLV_LEN(mtc
->ras
) = SUBTLV_DEF_SIZE
;
403 mtc
->ras
.value
= htonl(as
);
406 static void unset_circuitparams_inter_as(struct mpls_te_circuit
*mtc
)
409 /* Reset the Remote ASBR IP address and then the associated AS number */
410 SUBTLV_TYPE(mtc
->rip
) = 0;
411 SUBTLV_LEN(mtc
->rip
) = 0;
412 mtc
->rip
.value
.s_addr
= 0;
414 SUBTLV_TYPE(mtc
->ras
) = 0;
415 SUBTLV_LEN(mtc
->ras
) = 0;
419 static void set_circuitparams_av_delay(struct mpls_te_circuit
*mtc
,
420 u_int32_t delay
, u_char anormal
)
423 /* Note that TLV-length field is the size of array. */
424 SUBTLV_TYPE(mtc
->av_delay
) = TE_SUBTLV_AV_DELAY
;
425 SUBTLV_LEN(mtc
->av_delay
) = SUBTLV_DEF_SIZE
;
426 tmp
= delay
& TE_EXT_MASK
;
428 tmp
|= TE_EXT_ANORMAL
;
429 mtc
->av_delay
.value
= htonl(tmp
);
433 static void set_circuitparams_mm_delay(struct mpls_te_circuit
*mtc
,
434 u_int32_t low
, u_int32_t high
,
438 /* Note that TLV-length field is the size of array. */
439 SUBTLV_TYPE(mtc
->mm_delay
) = TE_SUBTLV_MM_DELAY
;
440 SUBTLV_LEN(mtc
->mm_delay
) = TE_SUBTLV_MM_DELAY_SIZE
;
441 tmp
= low
& TE_EXT_MASK
;
443 tmp
|= TE_EXT_ANORMAL
;
444 mtc
->mm_delay
.low
= htonl(tmp
);
445 mtc
->mm_delay
.high
= htonl(high
);
449 static void set_circuitparams_delay_var(struct mpls_te_circuit
*mtc
,
452 /* Note that TLV-length field is the size of array. */
453 SUBTLV_TYPE(mtc
->delay_var
) = TE_SUBTLV_DELAY_VAR
;
454 SUBTLV_LEN(mtc
->delay_var
) = SUBTLV_DEF_SIZE
;
455 mtc
->delay_var
.value
= htonl(jitter
& TE_EXT_MASK
);
459 static void set_circuitparams_pkt_loss(struct mpls_te_circuit
*mtc
,
460 u_int32_t loss
, u_char anormal
)
463 /* Note that TLV-length field is the size of array. */
464 SUBTLV_TYPE(mtc
->pkt_loss
) = TE_SUBTLV_PKT_LOSS
;
465 SUBTLV_LEN(mtc
->pkt_loss
) = SUBTLV_DEF_SIZE
;
466 tmp
= loss
& TE_EXT_MASK
;
468 tmp
|= TE_EXT_ANORMAL
;
469 mtc
->pkt_loss
.value
= htonl(tmp
);
473 static void set_circuitparams_res_bw(struct mpls_te_circuit
*mtc
, float fp
)
475 /* Note that TLV-length field is the size of array. */
476 SUBTLV_TYPE(mtc
->res_bw
) = TE_SUBTLV_RES_BW
;
477 SUBTLV_LEN(mtc
->res_bw
) = SUBTLV_DEF_SIZE
;
478 mtc
->res_bw
.value
= htonf(fp
);
482 static void set_circuitparams_ava_bw(struct mpls_te_circuit
*mtc
, float fp
)
484 /* Note that TLV-length field is the size of array. */
485 SUBTLV_TYPE(mtc
->ava_bw
) = TE_SUBTLV_AVA_BW
;
486 SUBTLV_LEN(mtc
->ava_bw
) = SUBTLV_DEF_SIZE
;
487 mtc
->ava_bw
.value
= htonf(fp
);
491 static void set_circuitparams_use_bw(struct mpls_te_circuit
*mtc
, float fp
)
493 /* Note that TLV-length field is the size of array. */
494 SUBTLV_TYPE(mtc
->use_bw
) = TE_SUBTLV_USE_BW
;
495 SUBTLV_LEN(mtc
->use_bw
) = SUBTLV_DEF_SIZE
;
496 mtc
->use_bw
.value
= htonf(fp
);
500 /* Main initialization / update function of the MPLS TE Circuit context */
501 /* Call when interface TE Link parameters are modified */
502 void isis_link_params_update(struct isis_circuit
*circuit
,
503 struct interface
*ifp
)
506 struct prefix_ipv4
*addr
;
507 struct mpls_te_circuit
*mtc
;
510 if ((circuit
== NULL
) || (ifp
== NULL
))
513 zlog_info("MPLS-TE: Initialize circuit parameters for interface %s",
516 /* Check if MPLS TE Circuit context has not been already created */
517 if (circuit
->mtc
== NULL
)
518 circuit
->mtc
= mpls_te_circuit_new();
522 /* Fulfil MTC TLV from ifp TE Link parameters */
523 if (HAS_LINK_PARAMS(ifp
)) {
524 mtc
->status
= enable
;
526 if (IS_PARAM_SET(ifp
->link_params
, LP_ADM_GRP
))
527 set_circuitparams_admin_grp(
528 mtc
, ifp
->link_params
->admin_grp
);
530 SUBTLV_TYPE(mtc
->admin_grp
) = 0;
532 /* If not already set, register local IP addr from ip_addr list
534 if (SUBTLV_TYPE(mtc
->local_ipaddr
) == 0) {
535 if (circuit
->ip_addrs
!= NULL
536 && listcount(circuit
->ip_addrs
) != 0) {
537 addr
= (struct prefix_ipv4
*)listgetdata(
538 (struct listnode
*)listhead(
540 set_circuitparams_local_ipaddr(mtc
,
545 /* If not already set, try to determine Remote IP addr if
547 if ((SUBTLV_TYPE(mtc
->rmt_ipaddr
) == 0)
548 && (circuit
->circ_type
== CIRCUIT_T_P2P
)) {
549 struct isis_adjacency
*adj
= circuit
->u
.p2p
.neighbor
;
550 if (adj
->ipv4_addrs
!= NULL
551 && listcount(adj
->ipv4_addrs
) != 0) {
552 struct in_addr
*ip_addr
;
553 ip_addr
= (struct in_addr
*)listgetdata(
554 (struct listnode
*)listhead(
556 set_circuitparams_rmt_ipaddr(mtc
, *ip_addr
);
560 if (IS_PARAM_SET(ifp
->link_params
, LP_MAX_BW
))
561 set_circuitparams_max_bw(mtc
, ifp
->link_params
->max_bw
);
563 SUBTLV_TYPE(mtc
->max_bw
) = 0;
565 if (IS_PARAM_SET(ifp
->link_params
, LP_MAX_RSV_BW
))
566 set_circuitparams_max_rsv_bw(
567 mtc
, ifp
->link_params
->max_rsv_bw
);
569 SUBTLV_TYPE(mtc
->max_rsv_bw
) = 0;
571 if (IS_PARAM_SET(ifp
->link_params
, LP_UNRSV_BW
))
572 for (i
= 0; i
< MAX_CLASS_TYPE
; i
++)
573 set_circuitparams_unrsv_bw(
574 mtc
, i
, ifp
->link_params
->unrsv_bw
[i
]);
576 SUBTLV_TYPE(mtc
->unrsv_bw
) = 0;
578 if (IS_PARAM_SET(ifp
->link_params
, LP_TE_METRIC
))
579 set_circuitparams_te_metric(
580 mtc
, ifp
->link_params
->te_metric
);
582 SUBTLV_TYPE(mtc
->te_metric
) = 0;
584 /* TE metric Extensions */
585 if (IS_PARAM_SET(ifp
->link_params
, LP_DELAY
))
586 set_circuitparams_av_delay(
587 mtc
, ifp
->link_params
->av_delay
, 0);
589 SUBTLV_TYPE(mtc
->av_delay
) = 0;
591 if (IS_PARAM_SET(ifp
->link_params
, LP_MM_DELAY
))
592 set_circuitparams_mm_delay(
593 mtc
, ifp
->link_params
->min_delay
,
594 ifp
->link_params
->max_delay
, 0);
596 SUBTLV_TYPE(mtc
->mm_delay
) = 0;
598 if (IS_PARAM_SET(ifp
->link_params
, LP_DELAY_VAR
))
599 set_circuitparams_delay_var(
600 mtc
, ifp
->link_params
->delay_var
);
602 SUBTLV_TYPE(mtc
->delay_var
) = 0;
604 if (IS_PARAM_SET(ifp
->link_params
, LP_PKT_LOSS
))
605 set_circuitparams_pkt_loss(
606 mtc
, ifp
->link_params
->pkt_loss
, 0);
608 SUBTLV_TYPE(mtc
->pkt_loss
) = 0;
610 if (IS_PARAM_SET(ifp
->link_params
, LP_RES_BW
))
611 set_circuitparams_res_bw(mtc
, ifp
->link_params
->res_bw
);
613 SUBTLV_TYPE(mtc
->res_bw
) = 0;
615 if (IS_PARAM_SET(ifp
->link_params
, LP_AVA_BW
))
616 set_circuitparams_ava_bw(mtc
, ifp
->link_params
->ava_bw
);
618 SUBTLV_TYPE(mtc
->ava_bw
) = 0;
620 if (IS_PARAM_SET(ifp
->link_params
, LP_USE_BW
))
621 set_circuitparams_use_bw(mtc
, ifp
->link_params
->use_bw
);
623 SUBTLV_TYPE(mtc
->use_bw
) = 0;
626 if (IS_PARAM_SET(ifp
->link_params
, LP_RMT_AS
))
627 set_circuitparams_inter_as(mtc
,
628 ifp
->link_params
->rmt_ip
,
629 ifp
->link_params
->rmt_as
);
631 /* reset inter-as TE params */
632 unset_circuitparams_inter_as(mtc
);
634 /* Compute total length of SUB TLVs */
635 mtc
->length
= subtlvs_len(mtc
);
638 mtc
->status
= disable
;
640 /* Finally Update LSP */
642 if (IS_MPLS_TE(isisMplsTE
) && circuit
->area
)
643 lsp_regenerate_schedule (circuit
->area
, circuit
->is_type
, 0);
648 void isis_mpls_te_update(struct interface
*ifp
)
650 struct isis_circuit
*circuit
;
656 /* Get circuit context from interface */
657 if ((circuit
= circuit_scan_by_ifp(ifp
)) == NULL
)
660 /* Update TE TLVs ... */
661 isis_link_params_update(circuit
, ifp
);
664 if (IS_MPLS_TE(isisMplsTE
) && circuit
->area
)
665 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
, 0);
670 /*------------------------------------------------------------------------*
671 * Followings are vty session control functions.
672 *------------------------------------------------------------------------*/
674 static u_char
show_vty_subtlv_admin_grp(struct vty
*vty
,
675 struct te_subtlv_admin_grp
*tlv
)
679 vty_out(vty
, " Administrative Group: 0x%x%s",
680 (u_int32_t
)ntohl(tlv
->value
), VTY_NEWLINE
);
682 zlog_debug(" Administrative Group: 0x%x",
683 (u_int32_t
)ntohl(tlv
->value
));
685 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
688 static u_char
show_vty_subtlv_llri(struct vty
*vty
, struct te_subtlv_llri
*tlv
)
691 vty_out(vty
, " Link Local ID: %d%s",
692 (u_int32_t
)ntohl(tlv
->local
), VTY_NEWLINE
);
693 vty_out(vty
, " Link Remote ID: %d%s",
694 (u_int32_t
)ntohl(tlv
->remote
), VTY_NEWLINE
);
696 zlog_debug(" Link Local ID: %d",
697 (u_int32_t
)ntohl(tlv
->local
));
698 zlog_debug(" Link Remote ID: %d",
699 (u_int32_t
)ntohl(tlv
->remote
));
702 return (SUBTLV_HDR_SIZE
+ TE_SUBTLV_LLRI_SIZE
);
705 static u_char
show_vty_subtlv_local_ipaddr(struct vty
*vty
,
706 struct te_subtlv_local_ipaddr
*tlv
)
709 vty_out(vty
, " Local Interface IP Address(es): %s%s",
710 inet_ntoa(tlv
->value
), VTY_NEWLINE
);
712 zlog_debug(" Local Interface IP Address(es): %s",
713 inet_ntoa(tlv
->value
));
715 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
718 static u_char
show_vty_subtlv_rmt_ipaddr(struct vty
*vty
,
719 struct te_subtlv_rmt_ipaddr
*tlv
)
722 vty_out(vty
, " Remote Interface IP Address(es): %s%s",
723 inet_ntoa(tlv
->value
), VTY_NEWLINE
);
725 zlog_debug(" Remote Interface IP Address(es): %s",
726 inet_ntoa(tlv
->value
));
728 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
731 static u_char
show_vty_subtlv_max_bw(struct vty
*vty
,
732 struct te_subtlv_max_bw
*tlv
)
736 fval
= ntohf(tlv
->value
);
739 vty_out(vty
, " Maximum Bandwidth: %g (Bytes/sec)%s", fval
,
742 zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval
);
744 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
747 static u_char
show_vty_subtlv_max_rsv_bw(struct vty
*vty
,
748 struct te_subtlv_max_rsv_bw
*tlv
)
752 fval
= ntohf(tlv
->value
);
756 " Maximum Reservable Bandwidth: %g (Bytes/sec)%s",
759 zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
762 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
765 static u_char
show_vty_subtlv_unrsv_bw(struct vty
*vty
,
766 struct te_subtlv_unrsv_bw
*tlv
)
772 vty_out(vty
, " Unreserved Bandwidth:%s", VTY_NEWLINE
);
774 zlog_debug(" Unreserved Bandwidth:");
776 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2) {
777 fval1
= ntohf(tlv
->value
[i
]);
778 fval2
= ntohf(tlv
->value
[i
+ 1]);
781 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
782 i
, fval1
, i
+ 1, fval2
, VTY_NEWLINE
);
785 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)",
786 i
, fval1
, i
+ 1, fval2
);
789 return (SUBTLV_HDR_SIZE
+ TE_SUBTLV_UNRSV_SIZE
);
792 static u_char
show_vty_subtlv_te_metric(struct vty
*vty
,
793 struct te_subtlv_te_metric
*tlv
)
797 te_metric
= tlv
->value
[2] | tlv
->value
[1] << 8 | tlv
->value
[0] << 16;
799 vty_out(vty
, " Traffic Engineering Metric: %u%s", te_metric
,
802 zlog_debug(" Traffic Engineering Metric: %u", te_metric
);
804 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
807 static u_char
show_vty_subtlv_ras(struct vty
*vty
, struct te_subtlv_ras
*tlv
)
810 vty_out(vty
, " Inter-AS TE Remote AS number: %u%s",
811 ntohl(tlv
->value
), VTY_NEWLINE
);
813 zlog_debug(" Inter-AS TE Remote AS number: %u",
816 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
819 static u_char
show_vty_subtlv_rip(struct vty
*vty
, struct te_subtlv_rip
*tlv
)
822 vty_out(vty
, " Inter-AS TE Remote ASBR IP address: %s%s",
823 inet_ntoa(tlv
->value
), VTY_NEWLINE
);
825 zlog_debug(" Inter-AS TE Remote ASBR IP address: %s",
826 inet_ntoa(tlv
->value
));
828 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
831 static u_char
show_vty_subtlv_av_delay(struct vty
*vty
,
832 struct te_subtlv_av_delay
*tlv
)
837 delay
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
838 A
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_ANORMAL
;
841 vty_out(vty
, " %s Average Link Delay: %d (micro-sec)%s",
842 A
? "Anomalous" : "Normal", delay
, VTY_NEWLINE
);
844 zlog_debug(" %s Average Link Delay: %d (micro-sec)",
845 A
? "Anomalous" : "Normal", delay
);
847 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
850 static u_char
show_vty_subtlv_mm_delay(struct vty
*vty
,
851 struct te_subtlv_mm_delay
*tlv
)
856 low
= (u_int32_t
)ntohl(tlv
->low
) & TE_EXT_MASK
;
857 A
= (u_int32_t
)ntohl(tlv
->low
) & TE_EXT_ANORMAL
;
858 high
= (u_int32_t
)ntohl(tlv
->high
) & TE_EXT_MASK
;
861 vty_out(vty
, " %s Min/Max Link Delay: %d / %d (micro-sec)%s",
862 A
? "Anomalous" : "Normal", low
, high
, VTY_NEWLINE
);
864 zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)",
865 A
? "Anomalous" : "Normal", low
, high
);
867 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
870 static u_char
show_vty_subtlv_delay_var(struct vty
*vty
,
871 struct te_subtlv_delay_var
*tlv
)
875 jitter
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
878 vty_out(vty
, " Delay Variation: %d (micro-sec)%s", jitter
,
881 zlog_debug(" Delay Variation: %d (micro-sec)", jitter
);
883 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
886 static u_char
show_vty_subtlv_pkt_loss(struct vty
*vty
,
887 struct te_subtlv_pkt_loss
*tlv
)
893 loss
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
894 fval
= (float)(loss
* LOSS_PRECISION
);
895 A
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_ANORMAL
;
898 vty_out(vty
, " %s Link Packet Loss: %g (%%)%s",
899 A
? "Anomalous" : "Normal", fval
, VTY_NEWLINE
);
901 zlog_debug(" %s Link Packet Loss: %g (%%)",
902 A
? "Anomalous" : "Normal", fval
);
904 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
907 static u_char
show_vty_subtlv_res_bw(struct vty
*vty
,
908 struct te_subtlv_res_bw
*tlv
)
912 fval
= ntohf(tlv
->value
);
916 " Unidirectional Residual Bandwidth: %g (Bytes/sec)%s",
920 " Unidirectional Residual Bandwidth: %g (Bytes/sec)",
923 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
926 static u_char
show_vty_subtlv_ava_bw(struct vty
*vty
,
927 struct te_subtlv_ava_bw
*tlv
)
931 fval
= ntohf(tlv
->value
);
935 " Unidirectional Available Bandwidth: %g (Bytes/sec)%s",
939 " Unidirectional Available Bandwidth: %g (Bytes/sec)",
942 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
945 static u_char
show_vty_subtlv_use_bw(struct vty
*vty
,
946 struct te_subtlv_use_bw
*tlv
)
950 fval
= ntohf(tlv
->value
);
954 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)%s",
958 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
961 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
964 static u_char
show_vty_unknown_tlv(struct vty
*vty
, struct subtlv_header
*tlvh
)
967 u_char
*v
= (u_char
*)tlvh
;
970 if (tlvh
->length
!= 0) {
972 " Unknown TLV: [type(%#.2x), length(%#.2x)]%s",
973 tlvh
->type
, tlvh
->length
, VTY_NEWLINE
);
974 vty_out(vty
, " Dump: [00]");
975 rtn
= 1; /* initialize end of line counter */
976 for (i
= 0; i
< tlvh
->length
; i
++) {
977 vty_out(vty
, " %#.2x", v
[i
]);
979 vty_out(vty
, "%s [%.2x]",
985 vty_out(vty
, "%s", VTY_NEWLINE
);
988 " Unknown TLV: [type(%#.2x), length(%#.2x)]%s",
989 tlvh
->type
, tlvh
->length
, VTY_NEWLINE
);
991 zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]",
992 tlvh
->type
, tlvh
->length
);
995 return SUBTLV_SIZE(tlvh
);
998 /* Main Show function */
999 void mpls_te_print_detail(struct vty
*vty
, struct te_is_neigh
*te
)
1001 struct subtlv_header
*tlvh
;
1004 zlog_debug("ISIS MPLS-TE: Show database TE detail");
1006 tlvh
= (struct subtlv_header
*)te
->sub_tlvs
;
1008 for (; sum
< te
->sub_tlvs_length
; tlvh
= SUBTLV_HDR_NEXT(tlvh
)) {
1009 switch (tlvh
->type
) {
1010 case TE_SUBTLV_ADMIN_GRP
:
1011 sum
+= show_vty_subtlv_admin_grp(
1012 vty
, (struct te_subtlv_admin_grp
*)tlvh
);
1014 case TE_SUBTLV_LLRI
:
1015 sum
+= show_vty_subtlv_llri(
1016 vty
, (struct te_subtlv_llri
*)tlvh
);
1018 case TE_SUBTLV_LOCAL_IPADDR
:
1019 sum
+= show_vty_subtlv_local_ipaddr(
1020 vty
, (struct te_subtlv_local_ipaddr
*)tlvh
);
1022 case TE_SUBTLV_RMT_IPADDR
:
1023 sum
+= show_vty_subtlv_rmt_ipaddr(
1024 vty
, (struct te_subtlv_rmt_ipaddr
*)tlvh
);
1026 case TE_SUBTLV_MAX_BW
:
1027 sum
+= show_vty_subtlv_max_bw(
1028 vty
, (struct te_subtlv_max_bw
*)tlvh
);
1030 case TE_SUBTLV_MAX_RSV_BW
:
1031 sum
+= show_vty_subtlv_max_rsv_bw(
1032 vty
, (struct te_subtlv_max_rsv_bw
*)tlvh
);
1034 case TE_SUBTLV_UNRSV_BW
:
1035 sum
+= show_vty_subtlv_unrsv_bw(
1036 vty
, (struct te_subtlv_unrsv_bw
*)tlvh
);
1038 case TE_SUBTLV_TE_METRIC
:
1039 sum
+= show_vty_subtlv_te_metric(
1040 vty
, (struct te_subtlv_te_metric
*)tlvh
);
1043 sum
+= show_vty_subtlv_ras(
1044 vty
, (struct te_subtlv_ras
*)tlvh
);
1047 sum
+= show_vty_subtlv_rip(
1048 vty
, (struct te_subtlv_rip
*)tlvh
);
1050 case TE_SUBTLV_AV_DELAY
:
1051 sum
+= show_vty_subtlv_av_delay(
1052 vty
, (struct te_subtlv_av_delay
*)tlvh
);
1054 case TE_SUBTLV_MM_DELAY
:
1055 sum
+= show_vty_subtlv_mm_delay(
1056 vty
, (struct te_subtlv_mm_delay
*)tlvh
);
1058 case TE_SUBTLV_DELAY_VAR
:
1059 sum
+= show_vty_subtlv_delay_var(
1060 vty
, (struct te_subtlv_delay_var
*)tlvh
);
1062 case TE_SUBTLV_PKT_LOSS
:
1063 sum
+= show_vty_subtlv_pkt_loss(
1064 vty
, (struct te_subtlv_pkt_loss
*)tlvh
);
1066 case TE_SUBTLV_RES_BW
:
1067 sum
+= show_vty_subtlv_res_bw(
1068 vty
, (struct te_subtlv_res_bw
*)tlvh
);
1070 case TE_SUBTLV_AVA_BW
:
1071 sum
+= show_vty_subtlv_ava_bw(
1072 vty
, (struct te_subtlv_ava_bw
*)tlvh
);
1074 case TE_SUBTLV_USE_BW
:
1075 sum
+= show_vty_subtlv_use_bw(
1076 vty
, (struct te_subtlv_use_bw
*)tlvh
);
1079 sum
+= show_vty_unknown_tlv(vty
, tlvh
);
1086 /* Specific MPLS TE router parameters write function */
1087 void isis_mpls_te_config_write_router(struct vty
*vty
)
1089 if (IS_MPLS_TE(isisMplsTE
)) {
1090 vty_out(vty
, " mpls-te on%s", VTY_NEWLINE
);
1091 vty_out(vty
, " mpls-te router-address %s%s",
1092 inet_ntoa(isisMplsTE
.router_id
), VTY_NEWLINE
);
1099 /*------------------------------------------------------------------------*
1100 * Followings are vty command functions.
1101 *------------------------------------------------------------------------*/
1103 DEFUN (isis_mpls_te_on
,
1104 isis_mpls_te_on_cmd
,
1107 "Enable MPLS-TE functionality\n")
1109 struct listnode
*node
;
1110 struct isis_circuit
*circuit
;
1112 if (IS_MPLS_TE(isisMplsTE
))
1115 if (IS_DEBUG_ISIS(DEBUG_TE
))
1116 zlog_debug("ISIS MPLS-TE: OFF -> ON");
1118 isisMplsTE
.status
= enable
;
1121 * Following code is intended to handle two cases;
1123 * 1) MPLS-TE was disabled at startup time, but now become enabled.
1124 * In this case, we must enable MPLS-TE Circuit regarding interface
1126 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1128 for (ALL_LIST_ELEMENTS_RO(isisMplsTE
.cir_list
, node
, circuit
)) {
1129 if (circuit
->mtc
== NULL
|| IS_FLOOD_AS(circuit
->mtc
->type
))
1132 if ((circuit
->mtc
->status
== disable
)
1133 && HAS_LINK_PARAMS(circuit
->interface
))
1134 circuit
->mtc
->status
= enable
;
1138 /* Reoriginate STD_TE & GMPLS circuits */
1140 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
,
1147 DEFUN (no_isis_mpls_te_on
,
1148 no_isis_mpls_te_on_cmd
,
1151 "Disable the MPLS-TE functionality\n")
1153 struct listnode
*node
;
1154 struct isis_circuit
*circuit
;
1156 if (isisMplsTE
.status
== disable
)
1159 if (IS_DEBUG_ISIS(DEBUG_TE
))
1160 zlog_debug("ISIS MPLS-TE: ON -> OFF");
1162 isisMplsTE
.status
= disable
;
1164 /* Flush LSP if circuit engage */
1165 for (ALL_LIST_ELEMENTS_RO(isisMplsTE
.cir_list
, node
, circuit
)) {
1166 if (circuit
->mtc
== NULL
|| (circuit
->mtc
->status
== disable
))
1169 /* disable MPLS_TE Circuit */
1170 circuit
->mtc
->status
= disable
;
1172 /* Re-originate circuit without STD_TE & GMPLS parameters */
1174 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
,
1181 DEFUN (isis_mpls_te_router_addr
,
1182 isis_mpls_te_router_addr_cmd
,
1183 "mpls-te router-address A.B.C.D",
1185 "Stable IP address of the advertising router\n"
1186 "MPLS-TE router address in IPv4 address format\n")
1189 struct in_addr value
;
1190 struct listnode
*node
;
1191 struct isis_area
*area
;
1193 if (!inet_aton(argv
[idx_ipv4
]->arg
, &value
)) {
1194 vty_out(vty
, "Please specify Router-Addr by A.B.C.D%s",
1199 isisMplsTE
.router_id
.s_addr
= value
.s_addr
;
1201 if (isisMplsTE
.status
== disable
)
1204 /* Update main Router ID in isis global structure */
1205 isis
->router_id
= value
.s_addr
;
1206 /* And re-schedule LSP update */
1207 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
))
1208 if (listcount(area
->area_addrs
) > 0)
1209 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1214 DEFUN (isis_mpls_te_inter_as
,
1215 isis_mpls_te_inter_as_cmd
,
1216 "mpls-te inter-as <level-1|level-1-2|level-2-only>",
1218 "Configure MPLS-TE Inter-AS support\n"
1219 "AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n"
1220 "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n"
1221 "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
1223 vty_out(vty
, "Not yet supported%s", VTY_NEWLINE
);
1227 DEFUN (no_isis_mpls_te_inter_as
,
1228 no_isis_mpls_te_inter_as_cmd
,
1229 "no mpls-te inter-as",
1231 "Disable the MPLS-TE functionality\n"
1232 "Disable MPLS-TE Inter-AS support\n")
1235 vty_out(vty
, "Not yet supported%s", VTY_NEWLINE
);
1239 DEFUN (show_isis_mpls_te_router
,
1240 show_isis_mpls_te_router_cmd
,
1241 "show isis mpls-te router",
1245 "Router information\n")
1247 if (IS_MPLS_TE(isisMplsTE
)) {
1248 vty_out(vty
, "--- MPLS-TE router parameters ---%s",
1251 if (ntohs(isisMplsTE
.router_id
.s_addr
) != 0)
1252 vty_out(vty
, " Router-Address: %s%s",
1253 inet_ntoa(isisMplsTE
.router_id
), VTY_NEWLINE
);
1255 vty_out(vty
, " N/A%s", VTY_NEWLINE
);
1257 vty_out(vty
, " MPLS-TE is disable on this router%s",
1263 static void show_mpls_te_sub(struct vty
*vty
, struct interface
*ifp
)
1265 struct mpls_te_circuit
*mtc
;
1267 if ((IS_MPLS_TE(isisMplsTE
))
1268 && ((mtc
= lookup_mpls_params_by_ifp(ifp
)) != NULL
)) {
1269 /* Continue only if interface is not passive or support Inter-AS
1271 if (mtc
->status
!= enable
) {
1272 if (IS_INTER_AS(mtc
->type
)) {
1274 "-- Inter-AS TEv2 link parameters for %s --%s",
1275 ifp
->name
, VTY_NEWLINE
);
1277 /* MPLS-TE is not activate on this interface */
1278 /* or this interface is passive and Inter-AS
1279 * TEv2 is not activate */
1281 " %s: MPLS-TE is disabled on this interface%s",
1282 ifp
->name
, VTY_NEWLINE
);
1286 vty_out(vty
, "-- MPLS-TE link parameters for %s --%s",
1287 ifp
->name
, VTY_NEWLINE
);
1290 show_vty_subtlv_admin_grp(vty
, &mtc
->admin_grp
);
1292 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0)
1293 show_vty_subtlv_local_ipaddr(vty
, &mtc
->local_ipaddr
);
1294 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0)
1295 show_vty_subtlv_rmt_ipaddr(vty
, &mtc
->rmt_ipaddr
);
1297 show_vty_subtlv_max_bw(vty
, &mtc
->max_bw
);
1298 show_vty_subtlv_max_rsv_bw(vty
, &mtc
->max_rsv_bw
);
1299 show_vty_subtlv_unrsv_bw(vty
, &mtc
->unrsv_bw
);
1300 show_vty_subtlv_te_metric(vty
, &mtc
->te_metric
);
1302 if (IS_INTER_AS(mtc
->type
)) {
1303 if (SUBTLV_TYPE(mtc
->ras
) != 0)
1304 show_vty_subtlv_ras(vty
, &mtc
->ras
);
1305 if (SUBTLV_TYPE(mtc
->rip
) != 0)
1306 show_vty_subtlv_rip(vty
, &mtc
->rip
);
1309 show_vty_subtlv_av_delay(vty
, &mtc
->av_delay
);
1310 show_vty_subtlv_mm_delay(vty
, &mtc
->mm_delay
);
1311 show_vty_subtlv_delay_var(vty
, &mtc
->delay_var
);
1312 show_vty_subtlv_pkt_loss(vty
, &mtc
->pkt_loss
);
1313 show_vty_subtlv_res_bw(vty
, &mtc
->res_bw
);
1314 show_vty_subtlv_ava_bw(vty
, &mtc
->ava_bw
);
1315 show_vty_subtlv_use_bw(vty
, &mtc
->use_bw
);
1316 vty_out(vty
, "---------------%s%s", VTY_NEWLINE
, VTY_NEWLINE
);
1318 vty_out(vty
, " %s: MPLS-TE is disabled on this interface%s",
1319 ifp
->name
, VTY_NEWLINE
);
1325 DEFUN (show_isis_mpls_te_interface
,
1326 show_isis_mpls_te_interface_cmd
,
1327 "show isis mpls-te interface [INTERFACE]",
1331 "Interface information\n"
1334 int idx_interface
= 4;
1335 struct interface
*ifp
;
1336 struct listnode
*node
;
1338 /* Show All Interfaces. */
1340 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
))
1341 show_mpls_te_sub(vty
, ifp
);
1343 /* Interface name is specified. */
1345 if ((ifp
= if_lookup_by_name(argv
[idx_interface
]->arg
,
1348 vty_out(vty
, "No such interface name%s", VTY_NEWLINE
);
1350 show_mpls_te_sub(vty
, ifp
);
1356 /* Initialize MPLS_TE */
1357 void isis_mpls_te_init(void)
1360 zlog_debug("ISIS MPLS-TE: Initialize");
1362 /* Initialize MPLS_TE structure */
1363 isisMplsTE
.status
= disable
;
1364 isisMplsTE
.level
= 0;
1365 isisMplsTE
.inter_as
= off
;
1366 isisMplsTE
.interas_areaid
.s_addr
= 0;
1367 isisMplsTE
.cir_list
= list_new();
1368 isisMplsTE
.router_id
.s_addr
= 0;
1370 /* Register new VTY commands */
1371 install_element(VIEW_NODE
, &show_isis_mpls_te_router_cmd
);
1372 install_element(VIEW_NODE
, &show_isis_mpls_te_interface_cmd
);
1374 install_element(ISIS_NODE
, &isis_mpls_te_on_cmd
);
1375 install_element(ISIS_NODE
, &no_isis_mpls_te_on_cmd
);
1376 install_element(ISIS_NODE
, &isis_mpls_te_router_addr_cmd
);
1377 install_element(ISIS_NODE
, &isis_mpls_te_inter_as_cmd
);
1378 install_element(ISIS_NODE
, &no_isis_mpls_te_inter_as_cmd
);