]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_te.c
release: FRR 3.0-rc1
[mirror_frr.git] / isisd / isis_te.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_te.c
3 *
4 * This is an implementation of RFC5305 & RFC 7810
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 "vrf.h"
41 #include "checksum.h"
42 #include "md5.h"
43 #include "sockunion.h"
44 #include "network.h"
45
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"
61
62 /* Global varial for MPLS TE management */
63 struct isis_mpls_te isisMplsTE;
64
65 const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"};
66
67 /*------------------------------------------------------------------------*
68 * Followings are control functions for MPLS-TE parameters management.
69 *------------------------------------------------------------------------*/
70
71 /* Search MPLS TE Circuit context from Interface */
72 static struct mpls_te_circuit *lookup_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 */
83 struct mpls_te_circuit *mpls_te_circuit_new()
84 {
85 struct mpls_te_circuit *mtc;
86
87 zlog_debug("ISIS MPLS-TE: Create new MPLS TE Circuit context");
88
89 mtc = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_circuit));
90
91 if (mtc == NULL)
92 return NULL;
93
94 mtc->status = disable;
95 mtc->type = STD_TE;
96 mtc->length = 0;
97
98 return mtc;
99 }
100
101 /* Copy SUB TLVs parameters into a buffer - No space verification are performed
102 */
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)
105 {
106 u_char size, *tlvs = buf;
107
108 zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
109
110 if (mtc == NULL) {
111 zlog_debug(
112 "ISIS MPLS-TE: Abort! No MPLS TE Circuit available has been specified");
113 return 0;
114 }
115
116 /* Create buffer if not provided */
117 if (buf == NULL) {
118 zlog_debug("ISIS MPLS-TE: Abort! No Buffer has been specified");
119 return 0;
120 }
121
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);
126 tlvs += size;
127 }
128
129 /* TE_SUBTLV_LLRI */
130 if (SUBTLV_TYPE(mtc->llri) != 0) {
131 size = SUBTLV_SIZE(&(mtc->llri.header));
132 memcpy(tlvs, &(mtc->llri), size);
133 tlvs += size;
134 }
135
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);
140 tlvs += size;
141 }
142
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);
147 tlvs += size;
148 }
149
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);
154 tlvs += size;
155 }
156
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);
161 tlvs += size;
162 }
163
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);
168 tlvs += size;
169 }
170
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);
175 tlvs += size;
176 }
177
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);
182 tlvs += size;
183 }
184
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);
189 tlvs += size;
190 }
191
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);
196 tlvs += size;
197 }
198
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);
203 tlvs += size;
204 }
205
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);
210 tlvs += size;
211 }
212
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);
217 tlvs += size;
218 }
219
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);
224 tlvs += size;
225 }
226
227 /* Update SubTLVs length */
228 mtc->length = subtlvs_len(mtc);
229
230 zlog_debug("ISIS MPLS-TE: Add %d bytes length SubTLVs", mtc->length);
231
232 return mtc->length;
233 }
234
235 /* Compute total Sub-TLVs size */
236 u_char subtlvs_len(struct mpls_te_circuit *mtc)
237 {
238 int length = 0;
239
240 /* Sanity Check */
241 if (mtc == NULL)
242 return 0;
243
244 /* TE_SUBTLV_ADMIN_GRP */
245 if (SUBTLV_TYPE(mtc->admin_grp) != 0)
246 length += SUBTLV_SIZE(&(mtc->admin_grp.header));
247
248 /* TE_SUBTLV_LLRI */
249 if (SUBTLV_TYPE(mtc->llri) != 0)
250 length += SUBTLV_SIZE(&mtc->llri.header);
251
252 /* TE_SUBTLV_LCLIF_IPADDR */
253 if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
254 length += SUBTLV_SIZE(&mtc->local_ipaddr.header);
255
256 /* TE_SUBTLV_RMTIF_IPADDR */
257 if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
258 length += SUBTLV_SIZE(&mtc->rmt_ipaddr.header);
259
260 /* TE_SUBTLV_MAX_BW */
261 if (SUBTLV_TYPE(mtc->max_bw) != 0)
262 length += SUBTLV_SIZE(&mtc->max_bw.header);
263
264 /* TE_SUBTLV_MAX_RSV_BW */
265 if (SUBTLV_TYPE(mtc->max_rsv_bw) != 0)
266 length += SUBTLV_SIZE(&mtc->max_rsv_bw.header);
267
268 /* TE_SUBTLV_UNRSV_BW */
269 if (SUBTLV_TYPE(mtc->unrsv_bw) != 0)
270 length += SUBTLV_SIZE(&mtc->unrsv_bw.header);
271
272 /* TE_SUBTLV_TE_METRIC */
273 if (SUBTLV_TYPE(mtc->te_metric) != 0)
274 length += SUBTLV_SIZE(&mtc->te_metric.header);
275
276 /* TE_SUBTLV_AV_DELAY */
277 if (SUBTLV_TYPE(mtc->av_delay) != 0)
278 length += SUBTLV_SIZE(&mtc->av_delay.header);
279
280 /* TE_SUBTLV_MM_DELAY */
281 if (SUBTLV_TYPE(mtc->mm_delay) != 0)
282 length += SUBTLV_SIZE(&mtc->mm_delay.header);
283
284 /* TE_SUBTLV_DELAY_VAR */
285 if (SUBTLV_TYPE(mtc->delay_var) != 0)
286 length += SUBTLV_SIZE(&mtc->delay_var.header);
287
288 /* TE_SUBTLV_PKT_LOSS */
289 if (SUBTLV_TYPE(mtc->pkt_loss) != 0)
290 length += SUBTLV_SIZE(&mtc->pkt_loss.header);
291
292 /* TE_SUBTLV_RES_BW */
293 if (SUBTLV_TYPE(mtc->res_bw) != 0)
294 length += SUBTLV_SIZE(&mtc->res_bw.header);
295
296 /* TE_SUBTLV_AVA_BW */
297 if (SUBTLV_TYPE(mtc->ava_bw) != 0)
298 length += SUBTLV_SIZE(&mtc->ava_bw.header);
299
300 /* TE_SUBTLV_USE_BW */
301 if (SUBTLV_TYPE(mtc->use_bw) != 0)
302 length += SUBTLV_SIZE(&mtc->use_bw.header);
303
304 /* Check that length is lower than the MAXIMUM SUBTLV size i.e. 256 */
305 if (length > MAX_SUBTLV_SIZE) {
306 mtc->length = 0;
307 return 0;
308 }
309
310 mtc->length = (u_char)length;
311
312 return mtc->length;
313 }
314
315 /* Following are various functions to set MPLS TE parameters */
316 static void set_circuitparams_admin_grp(struct mpls_te_circuit *mtc,
317 u_int32_t admingrp)
318 {
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);
322 return;
323 }
324
325 static void __attribute__((unused))
326 set_circuitparams_llri(struct mpls_te_circuit *mtc, u_int32_t local,
327 u_int32_t remote)
328 {
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);
333 }
334
335 void set_circuitparams_local_ipaddr(struct mpls_te_circuit *mtc,
336 struct in_addr addr)
337 {
338
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;
342 return;
343 }
344
345 void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *mtc,
346 struct in_addr addr)
347 {
348
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;
352 return;
353 }
354
355 static void set_circuitparams_max_bw(struct mpls_te_circuit *mtc, float fp)
356 {
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);
360 return;
361 }
362
363 static void set_circuitparams_max_rsv_bw(struct mpls_te_circuit *mtc, float fp)
364 {
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);
368 return;
369 }
370
371 static void set_circuitparams_unrsv_bw(struct mpls_te_circuit *mtc,
372 int priority, float fp)
373 {
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);
378 return;
379 }
380
381 static void set_circuitparams_te_metric(struct mpls_te_circuit *mtc,
382 u_int32_t te_metric)
383 {
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;
389 return;
390 }
391
392 static void set_circuitparams_inter_as(struct mpls_te_circuit *mtc,
393 struct in_addr addr, u_int32_t as)
394 {
395
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;
400
401 SUBTLV_TYPE(mtc->ras) = TE_SUBTLV_RAS;
402 SUBTLV_LEN(mtc->ras) = SUBTLV_DEF_SIZE;
403 mtc->ras.value = htonl(as);
404 }
405
406 static void unset_circuitparams_inter_as(struct mpls_te_circuit *mtc)
407 {
408
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;
413
414 SUBTLV_TYPE(mtc->ras) = 0;
415 SUBTLV_LEN(mtc->ras) = 0;
416 mtc->ras.value = 0;
417 }
418
419 static void set_circuitparams_av_delay(struct mpls_te_circuit *mtc,
420 u_int32_t delay, u_char anormal)
421 {
422 u_int32_t tmp;
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;
427 if (anormal)
428 tmp |= TE_EXT_ANORMAL;
429 mtc->av_delay.value = htonl(tmp);
430 return;
431 }
432
433 static void set_circuitparams_mm_delay(struct mpls_te_circuit *mtc,
434 u_int32_t low, u_int32_t high,
435 u_char anormal)
436 {
437 u_int32_t tmp;
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;
442 if (anormal)
443 tmp |= TE_EXT_ANORMAL;
444 mtc->mm_delay.low = htonl(tmp);
445 mtc->mm_delay.high = htonl(high);
446 return;
447 }
448
449 static void set_circuitparams_delay_var(struct mpls_te_circuit *mtc,
450 u_int32_t jitter)
451 {
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);
456 return;
457 }
458
459 static void set_circuitparams_pkt_loss(struct mpls_te_circuit *mtc,
460 u_int32_t loss, u_char anormal)
461 {
462 u_int32_t tmp;
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;
467 if (anormal)
468 tmp |= TE_EXT_ANORMAL;
469 mtc->pkt_loss.value = htonl(tmp);
470 return;
471 }
472
473 static void set_circuitparams_res_bw(struct mpls_te_circuit *mtc, float fp)
474 {
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);
479 return;
480 }
481
482 static void set_circuitparams_ava_bw(struct mpls_te_circuit *mtc, float fp)
483 {
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);
488 return;
489 }
490
491 static void set_circuitparams_use_bw(struct mpls_te_circuit *mtc, float fp)
492 {
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);
497 return;
498 }
499
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)
504 {
505 int i;
506 struct prefix_ipv4 *addr;
507 struct mpls_te_circuit *mtc;
508
509 /* Sanity Check */
510 if ((circuit == NULL) || (ifp == NULL))
511 return;
512
513 zlog_info("MPLS-TE: Initialize circuit parameters for interface %s",
514 ifp->name);
515
516 /* Check if MPLS TE Circuit context has not been already created */
517 if (circuit->mtc == NULL)
518 circuit->mtc = mpls_te_circuit_new();
519
520 mtc = circuit->mtc;
521
522 /* Fulfil MTC TLV from ifp TE Link parameters */
523 if (HAS_LINK_PARAMS(ifp)) {
524 mtc->status = enable;
525 /* STD_TE metrics */
526 if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP))
527 set_circuitparams_admin_grp(
528 mtc, ifp->link_params->admin_grp);
529 else
530 SUBTLV_TYPE(mtc->admin_grp) = 0;
531
532 /* If not already set, register local IP addr from ip_addr list
533 * if it exists */
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(
539 circuit->ip_addrs));
540 set_circuitparams_local_ipaddr(mtc,
541 addr->prefix);
542 }
543 }
544
545 /* If not already set, try to determine Remote IP addr if
546 * circuit is P2P */
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(
555 adj->ipv4_addrs));
556 set_circuitparams_rmt_ipaddr(mtc, *ip_addr);
557 }
558 }
559
560 if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW))
561 set_circuitparams_max_bw(mtc, ifp->link_params->max_bw);
562 else
563 SUBTLV_TYPE(mtc->max_bw) = 0;
564
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);
568 else
569 SUBTLV_TYPE(mtc->max_rsv_bw) = 0;
570
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]);
575 else
576 SUBTLV_TYPE(mtc->unrsv_bw) = 0;
577
578 if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC))
579 set_circuitparams_te_metric(
580 mtc, ifp->link_params->te_metric);
581 else
582 SUBTLV_TYPE(mtc->te_metric) = 0;
583
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);
588 else
589 SUBTLV_TYPE(mtc->av_delay) = 0;
590
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);
595 else
596 SUBTLV_TYPE(mtc->mm_delay) = 0;
597
598 if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR))
599 set_circuitparams_delay_var(
600 mtc, ifp->link_params->delay_var);
601 else
602 SUBTLV_TYPE(mtc->delay_var) = 0;
603
604 if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS))
605 set_circuitparams_pkt_loss(
606 mtc, ifp->link_params->pkt_loss, 0);
607 else
608 SUBTLV_TYPE(mtc->pkt_loss) = 0;
609
610 if (IS_PARAM_SET(ifp->link_params, LP_RES_BW))
611 set_circuitparams_res_bw(mtc, ifp->link_params->res_bw);
612 else
613 SUBTLV_TYPE(mtc->res_bw) = 0;
614
615 if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW))
616 set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw);
617 else
618 SUBTLV_TYPE(mtc->ava_bw) = 0;
619
620 if (IS_PARAM_SET(ifp->link_params, LP_USE_BW))
621 set_circuitparams_use_bw(mtc, ifp->link_params->use_bw);
622 else
623 SUBTLV_TYPE(mtc->use_bw) = 0;
624
625 /* INTER_AS */
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);
630 else
631 /* reset inter-as TE params */
632 unset_circuitparams_inter_as(mtc);
633
634 /* Compute total length of SUB TLVs */
635 mtc->length = subtlvs_len(mtc);
636
637 } else
638 mtc->status = disable;
639
640 /* Finally Update LSP */
641 #if 0
642 if (IS_MPLS_TE(isisMplsTE) && circuit->area)
643 lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
644 #endif
645 return;
646 }
647
648 void isis_mpls_te_update(struct interface *ifp)
649 {
650 struct isis_circuit *circuit;
651
652 /* Sanity Check */
653 if (ifp == NULL)
654 return;
655
656 /* Get circuit context from interface */
657 if ((circuit = circuit_scan_by_ifp(ifp)) == NULL)
658 return;
659
660 /* Update TE TLVs ... */
661 isis_link_params_update(circuit, ifp);
662
663 /* ... and LSP */
664 if (IS_MPLS_TE(isisMplsTE) && circuit->area)
665 lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
666
667 return;
668 }
669
670 /*------------------------------------------------------------------------*
671 * Followings are vty session control functions.
672 *------------------------------------------------------------------------*/
673
674 static u_char show_vty_subtlv_admin_grp(struct vty *vty,
675 struct te_subtlv_admin_grp *tlv)
676 {
677
678 if (vty != NULL)
679 vty_out(vty, " Administrative Group: 0x%x%s",
680 (u_int32_t)ntohl(tlv->value), VTY_NEWLINE);
681 else
682 zlog_debug(" Administrative Group: 0x%x",
683 (u_int32_t)ntohl(tlv->value));
684
685 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
686 }
687
688 static u_char show_vty_subtlv_llri(struct vty *vty, struct te_subtlv_llri *tlv)
689 {
690 if (vty != NULL) {
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);
695 } else {
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));
700 }
701
702 return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE);
703 }
704
705 static u_char show_vty_subtlv_local_ipaddr(struct vty *vty,
706 struct te_subtlv_local_ipaddr *tlv)
707 {
708 if (vty != NULL)
709 vty_out(vty, " Local Interface IP Address(es): %s%s",
710 inet_ntoa(tlv->value), VTY_NEWLINE);
711 else
712 zlog_debug(" Local Interface IP Address(es): %s",
713 inet_ntoa(tlv->value));
714
715 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
716 }
717
718 static u_char show_vty_subtlv_rmt_ipaddr(struct vty *vty,
719 struct te_subtlv_rmt_ipaddr *tlv)
720 {
721 if (vty != NULL)
722 vty_out(vty, " Remote Interface IP Address(es): %s%s",
723 inet_ntoa(tlv->value), VTY_NEWLINE);
724 else
725 zlog_debug(" Remote Interface IP Address(es): %s",
726 inet_ntoa(tlv->value));
727
728 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
729 }
730
731 static u_char show_vty_subtlv_max_bw(struct vty *vty,
732 struct te_subtlv_max_bw *tlv)
733 {
734 float fval;
735
736 fval = ntohf(tlv->value);
737
738 if (vty != NULL)
739 vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)%s", fval,
740 VTY_NEWLINE);
741 else
742 zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
743
744 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
745 }
746
747 static u_char show_vty_subtlv_max_rsv_bw(struct vty *vty,
748 struct te_subtlv_max_rsv_bw *tlv)
749 {
750 float fval;
751
752 fval = ntohf(tlv->value);
753
754 if (vty != NULL)
755 vty_out(vty,
756 " Maximum Reservable Bandwidth: %g (Bytes/sec)%s",
757 fval, VTY_NEWLINE);
758 else
759 zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
760 fval);
761
762 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
763 }
764
765 static u_char show_vty_subtlv_unrsv_bw(struct vty *vty,
766 struct te_subtlv_unrsv_bw *tlv)
767 {
768 float fval1, fval2;
769 int i;
770
771 if (vty != NULL)
772 vty_out(vty, " Unreserved Bandwidth:%s", VTY_NEWLINE);
773 else
774 zlog_debug(" Unreserved Bandwidth:");
775
776 for (i = 0; i < MAX_CLASS_TYPE; i += 2) {
777 fval1 = ntohf(tlv->value[i]);
778 fval2 = ntohf(tlv->value[i + 1]);
779 if (vty != NULL)
780 vty_out(vty,
781 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
782 i, fval1, i + 1, fval2, VTY_NEWLINE);
783 else
784 zlog_debug(
785 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)",
786 i, fval1, i + 1, fval2);
787 }
788
789 return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
790 }
791
792 static u_char show_vty_subtlv_te_metric(struct vty *vty,
793 struct te_subtlv_te_metric *tlv)
794 {
795 u_int32_t te_metric;
796
797 te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16;
798 if (vty != NULL)
799 vty_out(vty, " Traffic Engineering Metric: %u%s", te_metric,
800 VTY_NEWLINE);
801 else
802 zlog_debug(" Traffic Engineering Metric: %u", te_metric);
803
804 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
805 }
806
807 static u_char show_vty_subtlv_ras(struct vty *vty, struct te_subtlv_ras *tlv)
808 {
809 if (vty != NULL)
810 vty_out(vty, " Inter-AS TE Remote AS number: %u%s",
811 ntohl(tlv->value), VTY_NEWLINE);
812 else
813 zlog_debug(" Inter-AS TE Remote AS number: %u",
814 ntohl(tlv->value));
815
816 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
817 }
818
819 static u_char show_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",
823 inet_ntoa(tlv->value), VTY_NEWLINE);
824 else
825 zlog_debug(" Inter-AS TE Remote ASBR IP address: %s",
826 inet_ntoa(tlv->value));
827
828 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
829 }
830
831 static u_char show_vty_subtlv_av_delay(struct vty *vty,
832 struct te_subtlv_av_delay *tlv)
833 {
834 u_int32_t delay;
835 u_int32_t A;
836
837 delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
838 A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
839
840 if (vty != NULL)
841 vty_out(vty, " %s Average Link Delay: %d (micro-sec)%s",
842 A ? "Anomalous" : "Normal", delay, VTY_NEWLINE);
843 else
844 zlog_debug(" %s Average Link Delay: %d (micro-sec)",
845 A ? "Anomalous" : "Normal", delay);
846
847 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
848 }
849
850 static u_char show_vty_subtlv_mm_delay(struct vty *vty,
851 struct te_subtlv_mm_delay *tlv)
852 {
853 u_int32_t low, high;
854 u_int32_t A;
855
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;
859
860 if (vty != NULL)
861 vty_out(vty, " %s Min/Max Link Delay: %d / %d (micro-sec)%s",
862 A ? "Anomalous" : "Normal", low, high, VTY_NEWLINE);
863 else
864 zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)",
865 A ? "Anomalous" : "Normal", low, high);
866
867 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
868 }
869
870 static u_char show_vty_subtlv_delay_var(struct vty *vty,
871 struct te_subtlv_delay_var *tlv)
872 {
873 u_int32_t jitter;
874
875 jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
876
877 if (vty != NULL)
878 vty_out(vty, " Delay Variation: %d (micro-sec)%s", jitter,
879 VTY_NEWLINE);
880 else
881 zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
882
883 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
884 }
885
886 static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
887 struct te_subtlv_pkt_loss *tlv)
888 {
889 u_int32_t loss;
890 u_int32_t A;
891 float fval;
892
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;
896
897 if (vty != NULL)
898 vty_out(vty, " %s Link Packet Loss: %g (%%)%s",
899 A ? "Anomalous" : "Normal", fval, VTY_NEWLINE);
900 else
901 zlog_debug(" %s Link Packet Loss: %g (%%)",
902 A ? "Anomalous" : "Normal", fval);
903
904 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
905 }
906
907 static u_char show_vty_subtlv_res_bw(struct vty *vty,
908 struct te_subtlv_res_bw *tlv)
909 {
910 float fval;
911
912 fval = ntohf(tlv->value);
913
914 if (vty != NULL)
915 vty_out(vty,
916 " Unidirectional Residual Bandwidth: %g (Bytes/sec)%s",
917 fval, VTY_NEWLINE);
918 else
919 zlog_debug(
920 " Unidirectional Residual Bandwidth: %g (Bytes/sec)",
921 fval);
922
923 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
924 }
925
926 static u_char show_vty_subtlv_ava_bw(struct vty *vty,
927 struct te_subtlv_ava_bw *tlv)
928 {
929 float fval;
930
931 fval = ntohf(tlv->value);
932
933 if (vty != NULL)
934 vty_out(vty,
935 " Unidirectional Available Bandwidth: %g (Bytes/sec)%s",
936 fval, VTY_NEWLINE);
937 else
938 zlog_debug(
939 " Unidirectional Available Bandwidth: %g (Bytes/sec)",
940 fval);
941
942 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
943 }
944
945 static u_char show_vty_subtlv_use_bw(struct vty *vty,
946 struct te_subtlv_use_bw *tlv)
947 {
948 float fval;
949
950 fval = ntohf(tlv->value);
951
952 if (vty != NULL)
953 vty_out(vty,
954 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)%s",
955 fval, VTY_NEWLINE);
956 else
957 zlog_debug(
958 " Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
959 fval);
960
961 return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
962 }
963
964 static u_char show_vty_unknown_tlv(struct vty *vty, struct subtlv_header *tlvh)
965 {
966 int i, rtn = 1;
967 u_char *v = (u_char *)tlvh;
968
969 if (vty != NULL) {
970 if (tlvh->length != 0) {
971 vty_out(vty,
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]);
978 if (rtn == 8) {
979 vty_out(vty, "%s [%.2x]",
980 VTY_NEWLINE, i + 1);
981 rtn = 1;
982 } else
983 rtn++;
984 }
985 vty_out(vty, "%s", VTY_NEWLINE);
986 } else
987 vty_out(vty,
988 " Unknown TLV: [type(%#.2x), length(%#.2x)]%s",
989 tlvh->type, tlvh->length, VTY_NEWLINE);
990 } else {
991 zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]",
992 tlvh->type, tlvh->length);
993 }
994
995 return SUBTLV_SIZE(tlvh);
996 }
997
998 /* Main Show function */
999 void mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te)
1000 {
1001 struct subtlv_header *tlvh;
1002 u_int16_t sum = 0;
1003
1004 zlog_debug("ISIS MPLS-TE: Show database TE detail");
1005
1006 tlvh = (struct subtlv_header *)te->sub_tlvs;
1007
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);
1013 break;
1014 case TE_SUBTLV_LLRI:
1015 sum += show_vty_subtlv_llri(
1016 vty, (struct te_subtlv_llri *)tlvh);
1017 break;
1018 case TE_SUBTLV_LOCAL_IPADDR:
1019 sum += show_vty_subtlv_local_ipaddr(
1020 vty, (struct te_subtlv_local_ipaddr *)tlvh);
1021 break;
1022 case TE_SUBTLV_RMT_IPADDR:
1023 sum += show_vty_subtlv_rmt_ipaddr(
1024 vty, (struct te_subtlv_rmt_ipaddr *)tlvh);
1025 break;
1026 case TE_SUBTLV_MAX_BW:
1027 sum += show_vty_subtlv_max_bw(
1028 vty, (struct te_subtlv_max_bw *)tlvh);
1029 break;
1030 case TE_SUBTLV_MAX_RSV_BW:
1031 sum += show_vty_subtlv_max_rsv_bw(
1032 vty, (struct te_subtlv_max_rsv_bw *)tlvh);
1033 break;
1034 case TE_SUBTLV_UNRSV_BW:
1035 sum += show_vty_subtlv_unrsv_bw(
1036 vty, (struct te_subtlv_unrsv_bw *)tlvh);
1037 break;
1038 case TE_SUBTLV_TE_METRIC:
1039 sum += show_vty_subtlv_te_metric(
1040 vty, (struct te_subtlv_te_metric *)tlvh);
1041 break;
1042 case TE_SUBTLV_RAS:
1043 sum += show_vty_subtlv_ras(
1044 vty, (struct te_subtlv_ras *)tlvh);
1045 break;
1046 case TE_SUBTLV_RIP:
1047 sum += show_vty_subtlv_rip(
1048 vty, (struct te_subtlv_rip *)tlvh);
1049 break;
1050 case TE_SUBTLV_AV_DELAY:
1051 sum += show_vty_subtlv_av_delay(
1052 vty, (struct te_subtlv_av_delay *)tlvh);
1053 break;
1054 case TE_SUBTLV_MM_DELAY:
1055 sum += show_vty_subtlv_mm_delay(
1056 vty, (struct te_subtlv_mm_delay *)tlvh);
1057 break;
1058 case TE_SUBTLV_DELAY_VAR:
1059 sum += show_vty_subtlv_delay_var(
1060 vty, (struct te_subtlv_delay_var *)tlvh);
1061 break;
1062 case TE_SUBTLV_PKT_LOSS:
1063 sum += show_vty_subtlv_pkt_loss(
1064 vty, (struct te_subtlv_pkt_loss *)tlvh);
1065 break;
1066 case TE_SUBTLV_RES_BW:
1067 sum += show_vty_subtlv_res_bw(
1068 vty, (struct te_subtlv_res_bw *)tlvh);
1069 break;
1070 case TE_SUBTLV_AVA_BW:
1071 sum += show_vty_subtlv_ava_bw(
1072 vty, (struct te_subtlv_ava_bw *)tlvh);
1073 break;
1074 case TE_SUBTLV_USE_BW:
1075 sum += show_vty_subtlv_use_bw(
1076 vty, (struct te_subtlv_use_bw *)tlvh);
1077 break;
1078 default:
1079 sum += show_vty_unknown_tlv(vty, tlvh);
1080 break;
1081 }
1082 }
1083 return;
1084 }
1085
1086 /* Specific MPLS TE router parameters write function */
1087 void isis_mpls_te_config_write_router(struct vty *vty)
1088 {
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);
1093 }
1094
1095 return;
1096 }
1097
1098
1099 /*------------------------------------------------------------------------*
1100 * Followings are vty command functions.
1101 *------------------------------------------------------------------------*/
1102
1103 DEFUN (isis_mpls_te_on,
1104 isis_mpls_te_on_cmd,
1105 "mpls-te on",
1106 MPLS_TE_STR
1107 "Enable MPLS-TE functionality\n")
1108 {
1109 struct listnode *node;
1110 struct isis_circuit *circuit;
1111
1112 if (IS_MPLS_TE(isisMplsTE))
1113 return CMD_SUCCESS;
1114
1115 if (IS_DEBUG_ISIS(DEBUG_TE))
1116 zlog_debug("ISIS MPLS-TE: OFF -> ON");
1117
1118 isisMplsTE.status = enable;
1119
1120 /*
1121 * Following code is intended to handle two cases;
1122 *
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
1125 * MPLS_TE flag
1126 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1127 */
1128 for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
1129 if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
1130 continue;
1131
1132 if ((circuit->mtc->status == disable)
1133 && HAS_LINK_PARAMS(circuit->interface))
1134 circuit->mtc->status = enable;
1135 else
1136 continue;
1137
1138 /* Reoriginate STD_TE & GMPLS circuits */
1139 if (circuit->area)
1140 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1141 0);
1142 }
1143
1144 return CMD_SUCCESS;
1145 }
1146
1147 DEFUN (no_isis_mpls_te_on,
1148 no_isis_mpls_te_on_cmd,
1149 "no mpls-te",
1150 NO_STR
1151 "Disable the MPLS-TE functionality\n")
1152 {
1153 struct listnode *node;
1154 struct isis_circuit *circuit;
1155
1156 if (isisMplsTE.status == disable)
1157 return CMD_SUCCESS;
1158
1159 if (IS_DEBUG_ISIS(DEBUG_TE))
1160 zlog_debug("ISIS MPLS-TE: ON -> OFF");
1161
1162 isisMplsTE.status = disable;
1163
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))
1167 continue;
1168
1169 /* disable MPLS_TE Circuit */
1170 circuit->mtc->status = disable;
1171
1172 /* Re-originate circuit without STD_TE & GMPLS parameters */
1173 if (circuit->area)
1174 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1175 0);
1176 }
1177
1178 return CMD_SUCCESS;
1179 }
1180
1181 DEFUN (isis_mpls_te_router_addr,
1182 isis_mpls_te_router_addr_cmd,
1183 "mpls-te router-address A.B.C.D",
1184 MPLS_TE_STR
1185 "Stable IP address of the advertising router\n"
1186 "MPLS-TE router address in IPv4 address format\n")
1187 {
1188 int idx_ipv4 = 2;
1189 struct in_addr value;
1190 struct listnode *node;
1191 struct isis_area *area;
1192
1193 if (!inet_aton(argv[idx_ipv4]->arg, &value)) {
1194 vty_out(vty, "Please specify Router-Addr by A.B.C.D%s",
1195 VTY_NEWLINE);
1196 return CMD_WARNING;
1197 }
1198
1199 isisMplsTE.router_id.s_addr = value.s_addr;
1200
1201 if (isisMplsTE.status == disable)
1202 return CMD_SUCCESS;
1203
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);
1210
1211 return CMD_SUCCESS;
1212 }
1213
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>",
1217 MPLS_TE_STR
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")
1222 {
1223 vty_out(vty, "Not yet supported%s", VTY_NEWLINE);
1224 return CMD_SUCCESS;
1225 }
1226
1227 DEFUN (no_isis_mpls_te_inter_as,
1228 no_isis_mpls_te_inter_as_cmd,
1229 "no mpls-te inter-as",
1230 NO_STR
1231 "Disable the MPLS-TE functionality\n"
1232 "Disable MPLS-TE Inter-AS support\n")
1233 {
1234
1235 vty_out(vty, "Not yet supported%s", VTY_NEWLINE);
1236 return CMD_SUCCESS;
1237 }
1238
1239 DEFUN (show_isis_mpls_te_router,
1240 show_isis_mpls_te_router_cmd,
1241 "show isis mpls-te router",
1242 SHOW_STR
1243 ISIS_STR
1244 MPLS_TE_STR
1245 "Router information\n")
1246 {
1247 if (IS_MPLS_TE(isisMplsTE)) {
1248 vty_out(vty, "--- MPLS-TE router parameters ---%s",
1249 VTY_NEWLINE);
1250
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);
1254 else
1255 vty_out(vty, " N/A%s", VTY_NEWLINE);
1256 } else
1257 vty_out(vty, " MPLS-TE is disable on this router%s",
1258 VTY_NEWLINE);
1259
1260 return CMD_SUCCESS;
1261 }
1262
1263 static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
1264 {
1265 struct mpls_te_circuit *mtc;
1266
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
1270 * TEv2 */
1271 if (mtc->status != enable) {
1272 if (IS_INTER_AS(mtc->type)) {
1273 vty_out(vty,
1274 "-- Inter-AS TEv2 link parameters for %s --%s",
1275 ifp->name, VTY_NEWLINE);
1276 } else {
1277 /* MPLS-TE is not activate on this interface */
1278 /* or this interface is passive and Inter-AS
1279 * TEv2 is not activate */
1280 vty_out(vty,
1281 " %s: MPLS-TE is disabled on this interface%s",
1282 ifp->name, VTY_NEWLINE);
1283 return;
1284 }
1285 } else {
1286 vty_out(vty, "-- MPLS-TE link parameters for %s --%s",
1287 ifp->name, VTY_NEWLINE);
1288 }
1289
1290 show_vty_subtlv_admin_grp(vty, &mtc->admin_grp);
1291
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);
1296
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);
1301
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);
1307 }
1308
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);
1317 } else {
1318 vty_out(vty, " %s: MPLS-TE is disabled on this interface%s",
1319 ifp->name, VTY_NEWLINE);
1320 }
1321
1322 return;
1323 }
1324
1325 DEFUN (show_isis_mpls_te_interface,
1326 show_isis_mpls_te_interface_cmd,
1327 "show isis mpls-te interface [INTERFACE]",
1328 SHOW_STR
1329 ISIS_STR
1330 MPLS_TE_STR
1331 "Interface information\n"
1332 "Interface name\n")
1333 {
1334 int idx_interface = 4;
1335 struct interface *ifp;
1336 struct listnode *node;
1337
1338 /* Show All Interfaces. */
1339 if (argc == 4) {
1340 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
1341 show_mpls_te_sub(vty, ifp);
1342 }
1343 /* Interface name is specified. */
1344 else {
1345 if ((ifp = if_lookup_by_name(argv[idx_interface]->arg,
1346 VRF_DEFAULT))
1347 == NULL)
1348 vty_out(vty, "No such interface name%s", VTY_NEWLINE);
1349 else
1350 show_mpls_te_sub(vty, ifp);
1351 }
1352
1353 return CMD_SUCCESS;
1354 }
1355
1356 /* Initialize MPLS_TE */
1357 void isis_mpls_te_init(void)
1358 {
1359
1360 zlog_debug("ISIS MPLS-TE: Initialize");
1361
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;
1369
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);
1373
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);
1379
1380 return;
1381 }