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