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 along
22 * with this program; see the file COPYING; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
42 #include "sockunion.h"
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"
61 /* Global varial for MPLS TE management */
62 struct isis_mpls_te isisMplsTE
;
64 const char *mode2text
[] = {"Disable", "Area", "AS", "Emulate"};
66 /*------------------------------------------------------------------------*
67 * Followings are control functions for MPLS-TE parameters management.
68 *------------------------------------------------------------------------*/
70 /* Search MPLS TE Circuit context from Interface */
71 static struct mpls_te_circuit
*lookup_mpls_params_by_ifp(struct interface
*ifp
)
73 struct isis_circuit
*circuit
;
75 if ((circuit
= circuit_scan_by_ifp(ifp
)) == NULL
)
81 /* Create new MPLS TE Circuit context */
82 struct mpls_te_circuit
*mpls_te_circuit_new()
84 struct mpls_te_circuit
*mtc
;
86 zlog_debug("ISIS MPLS-TE: Create new MPLS TE Circuit context");
88 mtc
= XCALLOC(MTYPE_ISIS_MPLS_TE
, sizeof(struct mpls_te_circuit
));
93 mtc
->status
= disable
;
100 /* Copy SUB TLVs parameters into a buffer - No space verification are performed
102 /* Caller must verify before that there is enough free space in the buffer */
103 u_char
add_te_subtlvs(u_char
*buf
, struct mpls_te_circuit
*mtc
)
105 u_char size
, *tlvs
= buf
;
107 zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
111 "ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified");
115 /* Create buffer if not provided */
117 zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified");
121 /* TE_SUBTLV_ADMIN_GRP */
122 if (SUBTLV_TYPE(mtc
->admin_grp
) != 0) {
123 size
= SUBTLV_SIZE(&(mtc
->admin_grp
.header
));
124 memcpy(tlvs
, &(mtc
->admin_grp
), size
);
129 if (SUBTLV_TYPE(mtc
->llri
) != 0) {
130 size
= SUBTLV_SIZE(&(mtc
->llri
.header
));
131 memcpy(tlvs
, &(mtc
->llri
), size
);
135 /* TE_SUBTLV_LCLIF_IPADDR */
136 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0) {
137 size
= SUBTLV_SIZE(&(mtc
->local_ipaddr
.header
));
138 memcpy(tlvs
, &(mtc
->local_ipaddr
), size
);
142 /* TE_SUBTLV_RMTIF_IPADDR */
143 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0) {
144 size
= SUBTLV_SIZE(&(mtc
->rmt_ipaddr
.header
));
145 memcpy(tlvs
, &(mtc
->rmt_ipaddr
), size
);
149 /* TE_SUBTLV_MAX_BW */
150 if (SUBTLV_TYPE(mtc
->max_bw
) != 0) {
151 size
= SUBTLV_SIZE(&(mtc
->max_bw
.header
));
152 memcpy(tlvs
, &(mtc
->max_bw
), size
);
156 /* TE_SUBTLV_MAX_RSV_BW */
157 if (SUBTLV_TYPE(mtc
->max_rsv_bw
) != 0) {
158 size
= SUBTLV_SIZE(&(mtc
->max_rsv_bw
.header
));
159 memcpy(tlvs
, &(mtc
->max_rsv_bw
), size
);
163 /* TE_SUBTLV_UNRSV_BW */
164 if (SUBTLV_TYPE(mtc
->unrsv_bw
) != 0) {
165 size
= SUBTLV_SIZE(&(mtc
->unrsv_bw
.header
));
166 memcpy(tlvs
, &(mtc
->unrsv_bw
), size
);
170 /* TE_SUBTLV_TE_METRIC */
171 if (SUBTLV_TYPE(mtc
->te_metric
) != 0) {
172 size
= SUBTLV_SIZE(&(mtc
->te_metric
.header
));
173 memcpy(tlvs
, &(mtc
->te_metric
), size
);
177 /* TE_SUBTLV_AV_DELAY */
178 if (SUBTLV_TYPE(mtc
->av_delay
) != 0) {
179 size
= SUBTLV_SIZE(&(mtc
->av_delay
.header
));
180 memcpy(tlvs
, &(mtc
->av_delay
), size
);
184 /* TE_SUBTLV_MM_DELAY */
185 if (SUBTLV_TYPE(mtc
->mm_delay
) != 0) {
186 size
= SUBTLV_SIZE(&(mtc
->mm_delay
.header
));
187 memcpy(tlvs
, &(mtc
->mm_delay
), size
);
191 /* TE_SUBTLV_DELAY_VAR */
192 if (SUBTLV_TYPE(mtc
->delay_var
) != 0) {
193 size
= SUBTLV_SIZE(&(mtc
->delay_var
.header
));
194 memcpy(tlvs
, &(mtc
->delay_var
), size
);
198 /* TE_SUBTLV_PKT_LOSS */
199 if (SUBTLV_TYPE(mtc
->pkt_loss
) != 0) {
200 size
= SUBTLV_SIZE(&(mtc
->pkt_loss
.header
));
201 memcpy(tlvs
, &(mtc
->pkt_loss
), size
);
205 /* TE_SUBTLV_RES_BW */
206 if (SUBTLV_TYPE(mtc
->res_bw
) != 0) {
207 size
= SUBTLV_SIZE(&(mtc
->res_bw
.header
));
208 memcpy(tlvs
, &(mtc
->res_bw
), size
);
212 /* TE_SUBTLV_AVA_BW */
213 if (SUBTLV_TYPE(mtc
->ava_bw
) != 0) {
214 size
= SUBTLV_SIZE(&(mtc
->ava_bw
.header
));
215 memcpy(tlvs
, &(mtc
->ava_bw
), size
);
219 /* TE_SUBTLV_USE_BW */
220 if (SUBTLV_TYPE(mtc
->use_bw
) != 0) {
221 size
= SUBTLV_SIZE(&(mtc
->use_bw
.header
));
222 memcpy(tlvs
, &(mtc
->use_bw
), size
);
226 /* Update SubTLVs length */
227 mtc
->length
= subtlvs_len(mtc
);
229 zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc
->length
);
234 /* Compute total Sub-TLVs size */
235 u_char
subtlvs_len(struct mpls_te_circuit
*mtc
)
243 /* TE_SUBTLV_ADMIN_GRP */
244 if (SUBTLV_TYPE(mtc
->admin_grp
) != 0)
245 length
+= SUBTLV_SIZE(&(mtc
->admin_grp
.header
));
248 if (SUBTLV_TYPE(mtc
->llri
) != 0)
249 length
+= SUBTLV_SIZE(&mtc
->llri
.header
);
251 /* TE_SUBTLV_LCLIF_IPADDR */
252 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0)
253 length
+= SUBTLV_SIZE(&mtc
->local_ipaddr
.header
);
255 /* TE_SUBTLV_RMTIF_IPADDR */
256 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0)
257 length
+= SUBTLV_SIZE(&mtc
->rmt_ipaddr
.header
);
259 /* TE_SUBTLV_MAX_BW */
260 if (SUBTLV_TYPE(mtc
->max_bw
) != 0)
261 length
+= SUBTLV_SIZE(&mtc
->max_bw
.header
);
263 /* TE_SUBTLV_MAX_RSV_BW */
264 if (SUBTLV_TYPE(mtc
->max_rsv_bw
) != 0)
265 length
+= SUBTLV_SIZE(&mtc
->max_rsv_bw
.header
);
267 /* TE_SUBTLV_UNRSV_BW */
268 if (SUBTLV_TYPE(mtc
->unrsv_bw
) != 0)
269 length
+= SUBTLV_SIZE(&mtc
->unrsv_bw
.header
);
271 /* TE_SUBTLV_TE_METRIC */
272 if (SUBTLV_TYPE(mtc
->te_metric
) != 0)
273 length
+= SUBTLV_SIZE(&mtc
->te_metric
.header
);
275 /* TE_SUBTLV_AV_DELAY */
276 if (SUBTLV_TYPE(mtc
->av_delay
) != 0)
277 length
+= SUBTLV_SIZE(&mtc
->av_delay
.header
);
279 /* TE_SUBTLV_MM_DELAY */
280 if (SUBTLV_TYPE(mtc
->mm_delay
) != 0)
281 length
+= SUBTLV_SIZE(&mtc
->mm_delay
.header
);
283 /* TE_SUBTLV_DELAY_VAR */
284 if (SUBTLV_TYPE(mtc
->delay_var
) != 0)
285 length
+= SUBTLV_SIZE(&mtc
->delay_var
.header
);
287 /* TE_SUBTLV_PKT_LOSS */
288 if (SUBTLV_TYPE(mtc
->pkt_loss
) != 0)
289 length
+= SUBTLV_SIZE(&mtc
->pkt_loss
.header
);
291 /* TE_SUBTLV_RES_BW */
292 if (SUBTLV_TYPE(mtc
->res_bw
) != 0)
293 length
+= SUBTLV_SIZE(&mtc
->res_bw
.header
);
295 /* TE_SUBTLV_AVA_BW */
296 if (SUBTLV_TYPE(mtc
->ava_bw
) != 0)
297 length
+= SUBTLV_SIZE(&mtc
->ava_bw
.header
);
299 /* TE_SUBTLV_USE_BW */
300 if (SUBTLV_TYPE(mtc
->use_bw
) != 0)
301 length
+= SUBTLV_SIZE(&mtc
->use_bw
.header
);
303 /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */
304 if (length
> MAX_SUBTLV_SIZE
) {
309 mtc
->length
= (u_char
)length
;
314 /* Following are various functions to set MPLS TE parameters */
315 static void set_circuitparams_admin_grp(struct mpls_te_circuit
*mtc
,
318 SUBTLV_TYPE(mtc
->admin_grp
) = TE_SUBTLV_ADMIN_GRP
;
319 SUBTLV_LEN(mtc
->admin_grp
) = SUBTLV_DEF_SIZE
;
320 mtc
->admin_grp
.value
= htonl(admingrp
);
324 static void __attribute__((unused
))
325 set_circuitparams_llri(struct mpls_te_circuit
*mtc
, u_int32_t local
,
328 SUBTLV_TYPE(mtc
->llri
) = TE_SUBTLV_LLRI
;
329 SUBTLV_LEN(mtc
->llri
) = TE_SUBTLV_LLRI_SIZE
;
330 mtc
->llri
.local
= htonl(local
);
331 mtc
->llri
.remote
= htonl(remote
);
334 void set_circuitparams_local_ipaddr(struct mpls_te_circuit
*mtc
,
338 SUBTLV_TYPE(mtc
->local_ipaddr
) = TE_SUBTLV_LOCAL_IPADDR
;
339 SUBTLV_LEN(mtc
->local_ipaddr
) = SUBTLV_DEF_SIZE
;
340 mtc
->local_ipaddr
.value
.s_addr
= addr
.s_addr
;
344 void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit
*mtc
,
348 SUBTLV_TYPE(mtc
->rmt_ipaddr
) = TE_SUBTLV_RMT_IPADDR
;
349 SUBTLV_LEN(mtc
->rmt_ipaddr
) = SUBTLV_DEF_SIZE
;
350 mtc
->rmt_ipaddr
.value
.s_addr
= addr
.s_addr
;
354 static void set_circuitparams_max_bw(struct mpls_te_circuit
*mtc
, float fp
)
356 SUBTLV_TYPE(mtc
->max_bw
) = TE_SUBTLV_MAX_BW
;
357 SUBTLV_LEN(mtc
->max_bw
) = SUBTLV_DEF_SIZE
;
358 mtc
->max_bw
.value
= htonf(fp
);
362 static void set_circuitparams_max_rsv_bw(struct mpls_te_circuit
*mtc
, float fp
)
364 SUBTLV_TYPE(mtc
->max_rsv_bw
) = TE_SUBTLV_MAX_RSV_BW
;
365 SUBTLV_LEN(mtc
->max_rsv_bw
) = SUBTLV_DEF_SIZE
;
366 mtc
->max_rsv_bw
.value
= htonf(fp
);
370 static void set_circuitparams_unrsv_bw(struct mpls_te_circuit
*mtc
,
371 int priority
, float fp
)
373 /* Note that TLV-length field is the size of array. */
374 SUBTLV_TYPE(mtc
->unrsv_bw
) = TE_SUBTLV_UNRSV_BW
;
375 SUBTLV_LEN(mtc
->unrsv_bw
) = TE_SUBTLV_UNRSV_SIZE
;
376 mtc
->unrsv_bw
.value
[priority
] = htonf(fp
);
380 static void set_circuitparams_te_metric(struct mpls_te_circuit
*mtc
,
383 SUBTLV_TYPE(mtc
->te_metric
) = TE_SUBTLV_TE_METRIC
;
384 SUBTLV_LEN(mtc
->te_metric
) = TE_SUBTLV_TE_METRIC_SIZE
;
385 mtc
->te_metric
.value
[0] = (te_metric
>> 16) & 0xFF;
386 mtc
->te_metric
.value
[1] = (te_metric
>> 8) & 0xFF;
387 mtc
->te_metric
.value
[2] = te_metric
& 0xFF;
391 static void set_circuitparams_inter_as(struct mpls_te_circuit
*mtc
,
392 struct in_addr addr
, u_int32_t as
)
395 /* Set the Remote ASBR IP address and then the associated AS number */
396 SUBTLV_TYPE(mtc
->rip
) = TE_SUBTLV_RIP
;
397 SUBTLV_LEN(mtc
->rip
) = SUBTLV_DEF_SIZE
;
398 mtc
->rip
.value
.s_addr
= addr
.s_addr
;
400 SUBTLV_TYPE(mtc
->ras
) = TE_SUBTLV_RAS
;
401 SUBTLV_LEN(mtc
->ras
) = SUBTLV_DEF_SIZE
;
402 mtc
->ras
.value
= htonl(as
);
405 static void unset_circuitparams_inter_as(struct mpls_te_circuit
*mtc
)
408 /* Reset the Remote ASBR IP address and then the associated AS number */
409 SUBTLV_TYPE(mtc
->rip
) = 0;
410 SUBTLV_LEN(mtc
->rip
) = 0;
411 mtc
->rip
.value
.s_addr
= 0;
413 SUBTLV_TYPE(mtc
->ras
) = 0;
414 SUBTLV_LEN(mtc
->ras
) = 0;
418 static void set_circuitparams_av_delay(struct mpls_te_circuit
*mtc
,
419 u_int32_t delay
, u_char anormal
)
422 /* Note that TLV-length field is the size of array. */
423 SUBTLV_TYPE(mtc
->av_delay
) = TE_SUBTLV_AV_DELAY
;
424 SUBTLV_LEN(mtc
->av_delay
) = SUBTLV_DEF_SIZE
;
425 tmp
= delay
& TE_EXT_MASK
;
427 tmp
|= TE_EXT_ANORMAL
;
428 mtc
->av_delay
.value
= htonl(tmp
);
432 static void set_circuitparams_mm_delay(struct mpls_te_circuit
*mtc
,
433 u_int32_t low
, u_int32_t high
,
437 /* Note that TLV-length field is the size of array. */
438 SUBTLV_TYPE(mtc
->mm_delay
) = TE_SUBTLV_MM_DELAY
;
439 SUBTLV_LEN(mtc
->mm_delay
) = TE_SUBTLV_MM_DELAY_SIZE
;
440 tmp
= low
& TE_EXT_MASK
;
442 tmp
|= TE_EXT_ANORMAL
;
443 mtc
->mm_delay
.low
= htonl(tmp
);
444 mtc
->mm_delay
.high
= htonl(high
);
448 static void set_circuitparams_delay_var(struct mpls_te_circuit
*mtc
,
451 /* Note that TLV-length field is the size of array. */
452 SUBTLV_TYPE(mtc
->delay_var
) = TE_SUBTLV_DELAY_VAR
;
453 SUBTLV_LEN(mtc
->delay_var
) = SUBTLV_DEF_SIZE
;
454 mtc
->delay_var
.value
= htonl(jitter
& TE_EXT_MASK
);
458 static void set_circuitparams_pkt_loss(struct mpls_te_circuit
*mtc
,
459 u_int32_t loss
, u_char anormal
)
462 /* Note that TLV-length field is the size of array. */
463 SUBTLV_TYPE(mtc
->pkt_loss
) = TE_SUBTLV_PKT_LOSS
;
464 SUBTLV_LEN(mtc
->pkt_loss
) = SUBTLV_DEF_SIZE
;
465 tmp
= loss
& TE_EXT_MASK
;
467 tmp
|= TE_EXT_ANORMAL
;
468 mtc
->pkt_loss
.value
= htonl(tmp
);
472 static void set_circuitparams_res_bw(struct mpls_te_circuit
*mtc
, float fp
)
474 /* Note that TLV-length field is the size of array. */
475 SUBTLV_TYPE(mtc
->res_bw
) = TE_SUBTLV_RES_BW
;
476 SUBTLV_LEN(mtc
->res_bw
) = SUBTLV_DEF_SIZE
;
477 mtc
->res_bw
.value
= htonf(fp
);
481 static void set_circuitparams_ava_bw(struct mpls_te_circuit
*mtc
, float fp
)
483 /* Note that TLV-length field is the size of array. */
484 SUBTLV_TYPE(mtc
->ava_bw
) = TE_SUBTLV_AVA_BW
;
485 SUBTLV_LEN(mtc
->ava_bw
) = SUBTLV_DEF_SIZE
;
486 mtc
->ava_bw
.value
= htonf(fp
);
490 static void set_circuitparams_use_bw(struct mpls_te_circuit
*mtc
, float fp
)
492 /* Note that TLV-length field is the size of array. */
493 SUBTLV_TYPE(mtc
->use_bw
) = TE_SUBTLV_USE_BW
;
494 SUBTLV_LEN(mtc
->use_bw
) = SUBTLV_DEF_SIZE
;
495 mtc
->use_bw
.value
= htonf(fp
);
499 /* Main initialization / update function of the MPLS TE Circuit context */
500 /* Call when interface TE Link parameters are modified */
501 void isis_link_params_update(struct isis_circuit
*circuit
,
502 struct interface
*ifp
)
505 struct prefix_ipv4
*addr
;
506 struct mpls_te_circuit
*mtc
;
509 if ((circuit
== NULL
) || (ifp
== NULL
))
512 zlog_info("MPLS-TE: Initialize circuit parameters for interface %s",
515 /* Check if MPLS TE Circuit context has not been already created */
516 if (circuit
->mtc
== NULL
)
517 circuit
->mtc
= mpls_te_circuit_new();
521 /* Fulfil MTC TLV from ifp TE Link parameters */
522 if (HAS_LINK_PARAMS(ifp
)) {
523 mtc
->status
= enable
;
525 if (IS_PARAM_SET(ifp
->link_params
, LP_ADM_GRP
))
526 set_circuitparams_admin_grp(
527 mtc
, ifp
->link_params
->admin_grp
);
529 SUBTLV_TYPE(mtc
->admin_grp
) = 0;
531 /* If not already set, register local IP addr from ip_addr list
533 if (SUBTLV_TYPE(mtc
->local_ipaddr
) == 0) {
534 if (circuit
->ip_addrs
!= NULL
535 && listcount(circuit
->ip_addrs
) != 0) {
536 addr
= (struct prefix_ipv4
*)listgetdata(
537 (struct listnode
*)listhead(
539 set_circuitparams_local_ipaddr(mtc
,
544 /* If not already set, try to determine Remote IP addr if
546 if ((SUBTLV_TYPE(mtc
->rmt_ipaddr
) == 0)
547 && (circuit
->circ_type
== CIRCUIT_T_P2P
)) {
548 struct isis_adjacency
*adj
= circuit
->u
.p2p
.neighbor
;
549 if (adj
->ipv4_addrs
!= NULL
550 && listcount(adj
->ipv4_addrs
) != 0) {
551 struct in_addr
*ip_addr
;
552 ip_addr
= (struct in_addr
*)listgetdata(
553 (struct listnode
*)listhead(
555 set_circuitparams_rmt_ipaddr(mtc
, *ip_addr
);
559 if (IS_PARAM_SET(ifp
->link_params
, LP_MAX_BW
))
560 set_circuitparams_max_bw(mtc
, ifp
->link_params
->max_bw
);
562 SUBTLV_TYPE(mtc
->max_bw
) = 0;
564 if (IS_PARAM_SET(ifp
->link_params
, LP_MAX_RSV_BW
))
565 set_circuitparams_max_rsv_bw(
566 mtc
, ifp
->link_params
->max_rsv_bw
);
568 SUBTLV_TYPE(mtc
->max_rsv_bw
) = 0;
570 if (IS_PARAM_SET(ifp
->link_params
, LP_UNRSV_BW
))
571 for (i
= 0; i
< MAX_CLASS_TYPE
; i
++)
572 set_circuitparams_unrsv_bw(
573 mtc
, i
, ifp
->link_params
->unrsv_bw
[i
]);
575 SUBTLV_TYPE(mtc
->unrsv_bw
) = 0;
577 if (IS_PARAM_SET(ifp
->link_params
, LP_TE_METRIC
))
578 set_circuitparams_te_metric(
579 mtc
, ifp
->link_params
->te_metric
);
581 SUBTLV_TYPE(mtc
->te_metric
) = 0;
583 /* TE metric Extensions */
584 if (IS_PARAM_SET(ifp
->link_params
, LP_DELAY
))
585 set_circuitparams_av_delay(
586 mtc
, ifp
->link_params
->av_delay
, 0);
588 SUBTLV_TYPE(mtc
->av_delay
) = 0;
590 if (IS_PARAM_SET(ifp
->link_params
, LP_MM_DELAY
))
591 set_circuitparams_mm_delay(
592 mtc
, ifp
->link_params
->min_delay
,
593 ifp
->link_params
->max_delay
, 0);
595 SUBTLV_TYPE(mtc
->mm_delay
) = 0;
597 if (IS_PARAM_SET(ifp
->link_params
, LP_DELAY_VAR
))
598 set_circuitparams_delay_var(
599 mtc
, ifp
->link_params
->delay_var
);
601 SUBTLV_TYPE(mtc
->delay_var
) = 0;
603 if (IS_PARAM_SET(ifp
->link_params
, LP_PKT_LOSS
))
604 set_circuitparams_pkt_loss(
605 mtc
, ifp
->link_params
->pkt_loss
, 0);
607 SUBTLV_TYPE(mtc
->pkt_loss
) = 0;
609 if (IS_PARAM_SET(ifp
->link_params
, LP_RES_BW
))
610 set_circuitparams_res_bw(mtc
, ifp
->link_params
->res_bw
);
612 SUBTLV_TYPE(mtc
->res_bw
) = 0;
614 if (IS_PARAM_SET(ifp
->link_params
, LP_AVA_BW
))
615 set_circuitparams_ava_bw(mtc
, ifp
->link_params
->ava_bw
);
617 SUBTLV_TYPE(mtc
->ava_bw
) = 0;
619 if (IS_PARAM_SET(ifp
->link_params
, LP_USE_BW
))
620 set_circuitparams_use_bw(mtc
, ifp
->link_params
->use_bw
);
622 SUBTLV_TYPE(mtc
->use_bw
) = 0;
625 if (IS_PARAM_SET(ifp
->link_params
, LP_RMT_AS
))
626 set_circuitparams_inter_as(mtc
,
627 ifp
->link_params
->rmt_ip
,
628 ifp
->link_params
->rmt_as
);
630 /* reset inter-as TE params */
631 unset_circuitparams_inter_as(mtc
);
633 /* Compute total length of SUB TLVs */
634 mtc
->length
= subtlvs_len(mtc
);
637 mtc
->status
= disable
;
639 /* Finally Update LSP */
641 if (IS_MPLS_TE(isisMplsTE
) && circuit
->area
)
642 lsp_regenerate_schedule (circuit
->area
, circuit
->is_type
, 0);
647 void isis_mpls_te_update(struct interface
*ifp
)
649 struct isis_circuit
*circuit
;
655 /* Get circuit context from interface */
656 if ((circuit
= circuit_scan_by_ifp(ifp
)) == NULL
)
659 /* Update TE TLVs ... */
660 isis_link_params_update(circuit
, ifp
);
663 if (IS_MPLS_TE(isisMplsTE
) && circuit
->area
)
664 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
, 0);
669 /*------------------------------------------------------------------------*
670 * Followings are vty session control functions.
671 *------------------------------------------------------------------------*/
673 static u_char
show_vty_subtlv_admin_grp(struct vty
*vty
,
674 struct te_subtlv_admin_grp
*tlv
)
678 vty_out(vty
, " Administrative Group: 0x%x\n",
679 (u_int32_t
)ntohl(tlv
->value
));
681 zlog_debug(" Administrative Group: 0x%x",
682 (u_int32_t
)ntohl(tlv
->value
));
684 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
687 static u_char
show_vty_subtlv_llri(struct vty
*vty
, struct te_subtlv_llri
*tlv
)
690 vty_out(vty
, " Link Local ID: %d\n",
691 (u_int32_t
)ntohl(tlv
->local
));
692 vty_out(vty
, " Link Remote ID: %d\n",
693 (u_int32_t
)ntohl(tlv
->remote
));
695 zlog_debug(" Link Local ID: %d",
696 (u_int32_t
)ntohl(tlv
->local
));
697 zlog_debug(" Link Remote ID: %d",
698 (u_int32_t
)ntohl(tlv
->remote
));
701 return (SUBTLV_HDR_SIZE
+ TE_SUBTLV_LLRI_SIZE
);
704 static u_char
show_vty_subtlv_local_ipaddr(struct vty
*vty
,
705 struct te_subtlv_local_ipaddr
*tlv
)
708 vty_out(vty
, " Local Interface IP Address(es): %s\n",
709 inet_ntoa(tlv
->value
));
711 zlog_debug(" Local Interface IP Address(es): %s",
712 inet_ntoa(tlv
->value
));
714 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
717 static u_char
show_vty_subtlv_rmt_ipaddr(struct vty
*vty
,
718 struct te_subtlv_rmt_ipaddr
*tlv
)
721 vty_out(vty
, " Remote Interface IP Address(es): %s\n",
722 inet_ntoa(tlv
->value
));
724 zlog_debug(" Remote Interface IP Address(es): %s",
725 inet_ntoa(tlv
->value
));
727 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
730 static u_char
show_vty_subtlv_max_bw(struct vty
*vty
,
731 struct te_subtlv_max_bw
*tlv
)
735 fval
= ntohf(tlv
->value
);
738 vty_out(vty
, " Maximum Bandwidth: %g (Bytes/sec)\n", fval
);
740 zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval
);
742 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
745 static u_char
show_vty_subtlv_max_rsv_bw(struct vty
*vty
,
746 struct te_subtlv_max_rsv_bw
*tlv
)
750 fval
= ntohf(tlv
->value
);
754 " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
757 zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
760 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
763 static u_char
show_vty_subtlv_unrsv_bw(struct vty
*vty
,
764 struct te_subtlv_unrsv_bw
*tlv
)
770 vty_out(vty
, " Unreserved Bandwidth:\n");
772 zlog_debug(" Unreserved Bandwidth:");
774 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2) {
775 fval1
= ntohf(tlv
->value
[i
]);
776 fval2
= ntohf(tlv
->value
[i
+ 1]);
779 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
780 i
, fval1
, i
+ 1, fval2
);
783 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)",
784 i
, fval1
, i
+ 1, fval2
);
787 return (SUBTLV_HDR_SIZE
+ TE_SUBTLV_UNRSV_SIZE
);
790 static u_char
show_vty_subtlv_te_metric(struct vty
*vty
,
791 struct te_subtlv_te_metric
*tlv
)
795 te_metric
= tlv
->value
[2] | tlv
->value
[1] << 8 | tlv
->value
[0] << 16;
797 vty_out(vty
, " Traffic Engineering Metric: %u\n", te_metric
);
799 zlog_debug(" Traffic Engineering Metric: %u", te_metric
);
801 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
804 static u_char
show_vty_subtlv_ras(struct vty
*vty
, struct te_subtlv_ras
*tlv
)
807 vty_out(vty
, " Inter-AS TE Remote AS number: %u\n",
810 zlog_debug(" Inter-AS TE Remote AS number: %u",
813 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
816 static u_char
show_vty_subtlv_rip(struct vty
*vty
, struct te_subtlv_rip
*tlv
)
819 vty_out(vty
, " Inter-AS TE Remote ASBR IP address: %s\n",
820 inet_ntoa(tlv
->value
));
822 zlog_debug(" Inter-AS TE Remote ASBR IP address: %s",
823 inet_ntoa(tlv
->value
));
825 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
828 static u_char
show_vty_subtlv_av_delay(struct vty
*vty
,
829 struct te_subtlv_av_delay
*tlv
)
834 delay
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
835 A
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_ANORMAL
;
838 vty_out(vty
, " %s Average Link Delay: %d (micro-sec)\n",
839 A
? "Anomalous" : "Normal", delay
);
841 zlog_debug(" %s Average Link Delay: %d (micro-sec)",
842 A
? "Anomalous" : "Normal", delay
);
844 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
847 static u_char
show_vty_subtlv_mm_delay(struct vty
*vty
,
848 struct te_subtlv_mm_delay
*tlv
)
853 low
= (u_int32_t
)ntohl(tlv
->low
) & TE_EXT_MASK
;
854 A
= (u_int32_t
)ntohl(tlv
->low
) & TE_EXT_ANORMAL
;
855 high
= (u_int32_t
)ntohl(tlv
->high
) & TE_EXT_MASK
;
858 vty_out(vty
, " %s Min/Max Link Delay: %d / %d (micro-sec)\n",
859 A
? "Anomalous" : "Normal", low
, high
);
861 zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)",
862 A
? "Anomalous" : "Normal", low
, high
);
864 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
867 static u_char
show_vty_subtlv_delay_var(struct vty
*vty
,
868 struct te_subtlv_delay_var
*tlv
)
872 jitter
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
875 vty_out(vty
, " Delay Variation: %d (micro-sec)\n", jitter
);
877 zlog_debug(" Delay Variation: %d (micro-sec)", jitter
);
879 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
882 static u_char
show_vty_subtlv_pkt_loss(struct vty
*vty
,
883 struct te_subtlv_pkt_loss
*tlv
)
889 loss
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_MASK
;
890 fval
= (float)(loss
* LOSS_PRECISION
);
891 A
= (u_int32_t
)ntohl(tlv
->value
) & TE_EXT_ANORMAL
;
894 vty_out(vty
, " %s Link Packet Loss: %g (%%)\n",
895 A
? "Anomalous" : "Normal", fval
);
897 zlog_debug(" %s Link Packet Loss: %g (%%)",
898 A
? "Anomalous" : "Normal", fval
);
900 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
903 static u_char
show_vty_subtlv_res_bw(struct vty
*vty
,
904 struct te_subtlv_res_bw
*tlv
)
908 fval
= ntohf(tlv
->value
);
912 " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
916 " Unidirectional Residual Bandwidth: %g (Bytes/sec)",
919 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
922 static u_char
show_vty_subtlv_ava_bw(struct vty
*vty
,
923 struct te_subtlv_ava_bw
*tlv
)
927 fval
= ntohf(tlv
->value
);
931 " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
935 " Unidirectional Available Bandwidth: %g (Bytes/sec)",
938 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
941 static u_char
show_vty_subtlv_use_bw(struct vty
*vty
,
942 struct te_subtlv_use_bw
*tlv
)
946 fval
= ntohf(tlv
->value
);
950 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
954 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
957 return (SUBTLV_HDR_SIZE
+ SUBTLV_DEF_SIZE
);
960 static u_char
show_vty_unknown_tlv(struct vty
*vty
, struct subtlv_header
*tlvh
)
963 u_char
*v
= (u_char
*)tlvh
;
966 if (tlvh
->length
!= 0) {
968 " Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
969 tlvh
->type
, tlvh
->length
);
970 vty_out(vty
, " Dump: [00]");
971 rtn
= 1; /* initialize end of line counter */
972 for (i
= 0; i
< tlvh
->length
; i
++) {
973 vty_out(vty
, " %#.2x", v
[i
]);
975 vty_out(vty
, "\n [%.2x]",
984 " Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
985 tlvh
->type
, tlvh
->length
);
987 zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]",
988 tlvh
->type
, tlvh
->length
);
991 return SUBTLV_SIZE(tlvh
);
994 /* Main Show function */
995 void mpls_te_print_detail(struct vty
*vty
, struct te_is_neigh
*te
)
997 struct subtlv_header
*tlvh
;
1000 zlog_debug("ISIS MPLS-TE: Show database TE detail");
1002 tlvh
= (struct subtlv_header
*)te
->sub_tlvs
;
1004 for (; sum
< te
->sub_tlvs_length
; tlvh
= SUBTLV_HDR_NEXT(tlvh
)) {
1005 switch (tlvh
->type
) {
1006 case TE_SUBTLV_ADMIN_GRP
:
1007 sum
+= show_vty_subtlv_admin_grp(
1008 vty
, (struct te_subtlv_admin_grp
*)tlvh
);
1010 case TE_SUBTLV_LLRI
:
1011 sum
+= show_vty_subtlv_llri(
1012 vty
, (struct te_subtlv_llri
*)tlvh
);
1014 case TE_SUBTLV_LOCAL_IPADDR
:
1015 sum
+= show_vty_subtlv_local_ipaddr(
1016 vty
, (struct te_subtlv_local_ipaddr
*)tlvh
);
1018 case TE_SUBTLV_RMT_IPADDR
:
1019 sum
+= show_vty_subtlv_rmt_ipaddr(
1020 vty
, (struct te_subtlv_rmt_ipaddr
*)tlvh
);
1022 case TE_SUBTLV_MAX_BW
:
1023 sum
+= show_vty_subtlv_max_bw(
1024 vty
, (struct te_subtlv_max_bw
*)tlvh
);
1026 case TE_SUBTLV_MAX_RSV_BW
:
1027 sum
+= show_vty_subtlv_max_rsv_bw(
1028 vty
, (struct te_subtlv_max_rsv_bw
*)tlvh
);
1030 case TE_SUBTLV_UNRSV_BW
:
1031 sum
+= show_vty_subtlv_unrsv_bw(
1032 vty
, (struct te_subtlv_unrsv_bw
*)tlvh
);
1034 case TE_SUBTLV_TE_METRIC
:
1035 sum
+= show_vty_subtlv_te_metric(
1036 vty
, (struct te_subtlv_te_metric
*)tlvh
);
1039 sum
+= show_vty_subtlv_ras(
1040 vty
, (struct te_subtlv_ras
*)tlvh
);
1043 sum
+= show_vty_subtlv_rip(
1044 vty
, (struct te_subtlv_rip
*)tlvh
);
1046 case TE_SUBTLV_AV_DELAY
:
1047 sum
+= show_vty_subtlv_av_delay(
1048 vty
, (struct te_subtlv_av_delay
*)tlvh
);
1050 case TE_SUBTLV_MM_DELAY
:
1051 sum
+= show_vty_subtlv_mm_delay(
1052 vty
, (struct te_subtlv_mm_delay
*)tlvh
);
1054 case TE_SUBTLV_DELAY_VAR
:
1055 sum
+= show_vty_subtlv_delay_var(
1056 vty
, (struct te_subtlv_delay_var
*)tlvh
);
1058 case TE_SUBTLV_PKT_LOSS
:
1059 sum
+= show_vty_subtlv_pkt_loss(
1060 vty
, (struct te_subtlv_pkt_loss
*)tlvh
);
1062 case TE_SUBTLV_RES_BW
:
1063 sum
+= show_vty_subtlv_res_bw(
1064 vty
, (struct te_subtlv_res_bw
*)tlvh
);
1066 case TE_SUBTLV_AVA_BW
:
1067 sum
+= show_vty_subtlv_ava_bw(
1068 vty
, (struct te_subtlv_ava_bw
*)tlvh
);
1070 case TE_SUBTLV_USE_BW
:
1071 sum
+= show_vty_subtlv_use_bw(
1072 vty
, (struct te_subtlv_use_bw
*)tlvh
);
1075 sum
+= show_vty_unknown_tlv(vty
, tlvh
);
1082 /* Specific MPLS TE router parameters write function */
1083 void isis_mpls_te_config_write_router(struct vty
*vty
)
1085 if (IS_MPLS_TE(isisMplsTE
)) {
1086 vty_out(vty
, " mpls-te on\n");
1087 vty_out(vty
, " mpls-te router-address %s\n",
1088 inet_ntoa(isisMplsTE
.router_id
));
1095 /*------------------------------------------------------------------------*
1096 * Followings are vty command functions.
1097 *------------------------------------------------------------------------*/
1099 DEFUN (isis_mpls_te_on
,
1100 isis_mpls_te_on_cmd
,
1103 "Enable MPLS-TE functionality\n")
1105 struct listnode
*node
;
1106 struct isis_circuit
*circuit
;
1108 if (IS_MPLS_TE(isisMplsTE
))
1111 if (IS_DEBUG_ISIS(DEBUG_TE
))
1112 zlog_debug("ISIS MPLS-TE: OFF -> ON");
1114 isisMplsTE
.status
= enable
;
1117 * Following code is intended to handle two cases;
1119 * 1) MPLS-TE was disabled at startup time, but now become enabled.
1120 * In this case, we must enable MPLS-TE Circuit regarding interface
1122 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1124 for (ALL_LIST_ELEMENTS_RO(isisMplsTE
.cir_list
, node
, circuit
)) {
1125 if (circuit
->mtc
== NULL
|| IS_FLOOD_AS(circuit
->mtc
->type
))
1128 if ((circuit
->mtc
->status
== disable
)
1129 && HAS_LINK_PARAMS(circuit
->interface
))
1130 circuit
->mtc
->status
= enable
;
1134 /* Reoriginate STD_TE & GMPLS circuits */
1136 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
,
1143 DEFUN (no_isis_mpls_te_on
,
1144 no_isis_mpls_te_on_cmd
,
1147 "Disable the MPLS-TE functionality\n")
1149 struct listnode
*node
;
1150 struct isis_circuit
*circuit
;
1152 if (isisMplsTE
.status
== disable
)
1155 if (IS_DEBUG_ISIS(DEBUG_TE
))
1156 zlog_debug("ISIS MPLS-TE: ON -> OFF");
1158 isisMplsTE
.status
= disable
;
1160 /* Flush LSP if circuit engage */
1161 for (ALL_LIST_ELEMENTS_RO(isisMplsTE
.cir_list
, node
, circuit
)) {
1162 if (circuit
->mtc
== NULL
|| (circuit
->mtc
->status
== disable
))
1165 /* disable MPLS_TE Circuit */
1166 circuit
->mtc
->status
= disable
;
1168 /* Re-originate circuit without STD_TE & GMPLS parameters */
1170 lsp_regenerate_schedule(circuit
->area
, circuit
->is_type
,
1177 DEFUN (isis_mpls_te_router_addr
,
1178 isis_mpls_te_router_addr_cmd
,
1179 "mpls-te router-address A.B.C.D",
1181 "Stable IP address of the advertising router\n"
1182 "MPLS-TE router address in IPv4 address format\n")
1185 struct in_addr value
;
1186 struct listnode
*node
;
1187 struct isis_area
*area
;
1189 if (!inet_aton(argv
[idx_ipv4
]->arg
, &value
)) {
1190 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
1191 return CMD_WARNING_CONFIG_FAILED
;
1194 isisMplsTE
.router_id
.s_addr
= value
.s_addr
;
1196 if (isisMplsTE
.status
== disable
)
1199 /* Update main Router ID in isis global structure */
1200 isis
->router_id
= value
.s_addr
;
1201 /* And re-schedule LSP update */
1202 for (ALL_LIST_ELEMENTS_RO(isis
->area_list
, node
, area
))
1203 if (listcount(area
->area_addrs
) > 0)
1204 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1209 DEFUN (isis_mpls_te_inter_as
,
1210 isis_mpls_te_inter_as_cmd
,
1211 "mpls-te inter-as <level-1|level-1-2|level-2-only>",
1213 "Configure MPLS-TE Inter-AS support\n"
1214 "AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n"
1215 "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n"
1216 "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
1218 vty_out(vty
, "Not yet supported\n");
1222 DEFUN (no_isis_mpls_te_inter_as
,
1223 no_isis_mpls_te_inter_as_cmd
,
1224 "no mpls-te inter-as",
1226 "Disable the MPLS-TE functionality\n"
1227 "Disable MPLS-TE Inter-AS support\n")
1230 vty_out(vty
, "Not yet supported\n");
1234 DEFUN (show_isis_mpls_te_router
,
1235 show_isis_mpls_te_router_cmd
,
1236 "show isis mpls-te router",
1240 "Router information\n")
1242 if (IS_MPLS_TE(isisMplsTE
)) {
1243 vty_out(vty
, "--- MPLS-TE router parameters ---\n");
1245 if (ntohs(isisMplsTE
.router_id
.s_addr
) != 0)
1246 vty_out(vty
, " Router-Address: %s\n",
1247 inet_ntoa(isisMplsTE
.router_id
));
1249 vty_out(vty
, " N/A\n");
1251 vty_out(vty
, " MPLS-TE is disable on this router\n");
1256 static void show_mpls_te_sub(struct vty
*vty
, struct interface
*ifp
)
1258 struct mpls_te_circuit
*mtc
;
1260 if ((IS_MPLS_TE(isisMplsTE
))
1261 && ((mtc
= lookup_mpls_params_by_ifp(ifp
)) != NULL
)) {
1262 /* Continue only if interface is not passive or support Inter-AS
1264 if (mtc
->status
!= enable
) {
1265 if (IS_INTER_AS(mtc
->type
)) {
1267 "-- Inter-AS TEv2 link parameters for %s --\n",
1270 /* MPLS-TE is not activate on this interface */
1271 /* or this interface is passive and Inter-AS
1272 * TEv2 is not activate */
1274 " %s: MPLS-TE is disabled on this interface\n",
1279 vty_out(vty
, "-- MPLS-TE link parameters for %s --\n",
1283 show_vty_subtlv_admin_grp(vty
, &mtc
->admin_grp
);
1285 if (SUBTLV_TYPE(mtc
->local_ipaddr
) != 0)
1286 show_vty_subtlv_local_ipaddr(vty
, &mtc
->local_ipaddr
);
1287 if (SUBTLV_TYPE(mtc
->rmt_ipaddr
) != 0)
1288 show_vty_subtlv_rmt_ipaddr(vty
, &mtc
->rmt_ipaddr
);
1290 show_vty_subtlv_max_bw(vty
, &mtc
->max_bw
);
1291 show_vty_subtlv_max_rsv_bw(vty
, &mtc
->max_rsv_bw
);
1292 show_vty_subtlv_unrsv_bw(vty
, &mtc
->unrsv_bw
);
1293 show_vty_subtlv_te_metric(vty
, &mtc
->te_metric
);
1295 if (IS_INTER_AS(mtc
->type
)) {
1296 if (SUBTLV_TYPE(mtc
->ras
) != 0)
1297 show_vty_subtlv_ras(vty
, &mtc
->ras
);
1298 if (SUBTLV_TYPE(mtc
->rip
) != 0)
1299 show_vty_subtlv_rip(vty
, &mtc
->rip
);
1302 show_vty_subtlv_av_delay(vty
, &mtc
->av_delay
);
1303 show_vty_subtlv_mm_delay(vty
, &mtc
->mm_delay
);
1304 show_vty_subtlv_delay_var(vty
, &mtc
->delay_var
);
1305 show_vty_subtlv_pkt_loss(vty
, &mtc
->pkt_loss
);
1306 show_vty_subtlv_res_bw(vty
, &mtc
->res_bw
);
1307 show_vty_subtlv_ava_bw(vty
, &mtc
->ava_bw
);
1308 show_vty_subtlv_use_bw(vty
, &mtc
->use_bw
);
1309 vty_out(vty
, "---------------\n\n");
1311 vty_out(vty
, " %s: MPLS-TE is disabled on this interface\n",
1318 DEFUN (show_isis_mpls_te_interface
,
1319 show_isis_mpls_te_interface_cmd
,
1320 "show isis mpls-te interface [INTERFACE]",
1324 "Interface information\n"
1327 int idx_interface
= 4;
1328 struct interface
*ifp
;
1329 struct listnode
*node
;
1331 /* Show All Interfaces. */
1333 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
))
1334 show_mpls_te_sub(vty
, ifp
);
1336 /* Interface name is specified. */
1338 if ((ifp
= if_lookup_by_name(argv
[idx_interface
]->arg
,
1341 vty_out(vty
, "No such interface name\n");
1343 show_mpls_te_sub(vty
, ifp
);
1349 /* Initialize MPLS_TE */
1350 void isis_mpls_te_init(void)
1353 zlog_debug("ISIS MPLS-TE: Initialize");
1355 /* Initialize MPLS_TE structure */
1356 isisMplsTE
.status
= disable
;
1357 isisMplsTE
.level
= 0;
1358 isisMplsTE
.inter_as
= off
;
1359 isisMplsTE
.interas_areaid
.s_addr
= 0;
1360 isisMplsTE
.cir_list
= list_new();
1361 isisMplsTE
.router_id
.s_addr
= 0;
1363 /* Register new VTY commands */
1364 install_element(VIEW_NODE
, &show_isis_mpls_te_router_cmd
);
1365 install_element(VIEW_NODE
, &show_isis_mpls_te_interface_cmd
);
1367 install_element(ISIS_NODE
, &isis_mpls_te_on_cmd
);
1368 install_element(ISIS_NODE
, &no_isis_mpls_te_on_cmd
);
1369 install_element(ISIS_NODE
, &isis_mpls_te_router_addr_cmd
);
1370 install_element(ISIS_NODE
, &isis_mpls_te_inter_as_cmd
);
1371 install_element(ISIS_NODE
, &no_isis_mpls_te_inter_as_cmd
);