]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_nb_config.c
Merge pull request #8672 from qlyoung/fix-bgp-timer-display
[mirror_frr.git] / isisd / isis_nb_config.c
1 /*
2 * Copyright (C) 2001,2002 Sampo Saaristo
3 * Tampere University of Technology
4 * Institute of Communications Engineering
5 * Copyright (C) 2018 Volta Networks
6 * Emanuele Di Pascale
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <zebra.h>
24
25 #include "printfrr.h"
26 #include "northbound.h"
27 #include "linklist.h"
28 #include "log.h"
29 #include "bfd.h"
30 #include "filter.h"
31 #include "plist.h"
32 #include "spf_backoff.h"
33 #include "lib_errors.h"
34 #include "vrf.h"
35 #include "ldp_sync.h"
36
37 #include "isisd/isisd.h"
38 #include "isisd/isis_nb.h"
39 #include "isisd/isis_common.h"
40 #include "isisd/isis_bfd.h"
41 #include "isisd/isis_circuit.h"
42 #include "isisd/isis_lsp.h"
43 #include "isisd/isis_dynhn.h"
44 #include "isisd/isis_misc.h"
45 #include "isisd/isis_csm.h"
46 #include "isisd/isis_adjacency.h"
47 #include "isisd/isis_spf.h"
48 #include "isisd/isis_spf_private.h"
49 #include "isisd/isis_te.h"
50 #include "isisd/isis_mt.h"
51 #include "isisd/isis_redist.h"
52 #include "isisd/isis_ldp_sync.h"
53 #include "isisd/isis_dr.h"
54
55 DEFINE_MTYPE_STATIC(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters");
56 DEFINE_MTYPE_STATIC(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name");
57
58 /*
59 * XPath: /frr-isisd:isis/instance
60 */
61 int isis_instance_create(struct nb_cb_create_args *args)
62 {
63 struct isis_area *area;
64 const char *area_tag;
65 const char *vrf_name;
66
67 if (args->event != NB_EV_APPLY)
68 return NB_OK;
69 vrf_name = yang_dnode_get_string(args->dnode, "./vrf");
70 area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
71 isis_global_instance_create(vrf_name);
72 area = isis_area_lookup_by_vrf(area_tag, vrf_name);
73 if (area)
74 return NB_ERR_INCONSISTENCY;
75
76 area = isis_area_create(area_tag, vrf_name);
77
78 /* save area in dnode to avoid looking it up all the time */
79 nb_running_set_entry(args->dnode, area);
80
81 return NB_OK;
82 }
83
84 int isis_instance_destroy(struct nb_cb_destroy_args *args)
85 {
86 struct isis_area *area;
87
88 if (args->event != NB_EV_APPLY)
89 return NB_OK;
90 area = nb_running_unset_entry(args->dnode);
91
92 isis_area_destroy(area);
93 return NB_OK;
94 }
95
96 /*
97 * XPath: /frr-isisd:isis/instance/is-type
98 */
99 int isis_instance_is_type_modify(struct nb_cb_modify_args *args)
100 {
101 struct isis_area *area;
102 int type;
103
104 if (args->event != NB_EV_APPLY)
105 return NB_OK;
106
107 area = nb_running_get_entry(args->dnode, NULL, true);
108 type = yang_dnode_get_enum(args->dnode, NULL);
109 isis_area_is_type_set(area, type);
110
111 return NB_OK;
112 }
113
114 /*
115 * XPath: /frr-isisd:isis/instance/area-address
116 */
117 int isis_instance_area_address_create(struct nb_cb_create_args *args)
118 {
119 struct isis_area *area;
120 struct area_addr addr, *addrr = NULL, *addrp = NULL;
121 struct listnode *node;
122 uint8_t buff[255];
123 const char *net_title = yang_dnode_get_string(args->dnode, NULL);
124
125 switch (args->event) {
126 case NB_EV_VALIDATE:
127 area = nb_running_get_entry(args->dnode, NULL, false);
128 if (area == NULL)
129 return NB_ERR_VALIDATION;
130 addr.addr_len = dotformat2buff(buff, net_title);
131 memcpy(addr.area_addr, buff, addr.addr_len);
132 if (addr.area_addr[addr.addr_len - 1] != 0) {
133 snprintf(
134 args->errmsg, args->errmsg_len,
135 "nsel byte (last byte) in area address must be 0");
136 return NB_ERR_VALIDATION;
137 }
138 if (area->isis->sysid_set) {
139 /* Check that the SystemID portions match */
140 if (memcmp(area->isis->sysid, GETSYSID((&addr)),
141 ISIS_SYS_ID_LEN)) {
142 snprintf(
143 args->errmsg, args->errmsg_len,
144 "System ID must not change when defining additional area addresses");
145 return NB_ERR_VALIDATION;
146 }
147 }
148 break;
149 case NB_EV_PREPARE:
150 addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
151 addrr->addr_len = dotformat2buff(buff, net_title);
152 memcpy(addrr->area_addr, buff, addrr->addr_len);
153 args->resource->ptr = addrr;
154 break;
155 case NB_EV_ABORT:
156 XFREE(MTYPE_ISIS_AREA_ADDR, args->resource->ptr);
157 break;
158 case NB_EV_APPLY:
159 area = nb_running_get_entry(args->dnode, NULL, true);
160 addrr = args->resource->ptr;
161 assert(area);
162
163 if (area->isis->sysid_set == 0) {
164 /*
165 * First area address - get the SystemID for this router
166 */
167 memcpy(area->isis->sysid, GETSYSID(addrr),
168 ISIS_SYS_ID_LEN);
169 area->isis->sysid_set = 1;
170 } else {
171 /* check that we don't already have this address */
172 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
173 addrp)) {
174 if ((addrp->addr_len + ISIS_SYS_ID_LEN
175 + ISIS_NSEL_LEN)
176 != (addrr->addr_len))
177 continue;
178 if (!memcmp(addrp->area_addr, addrr->area_addr,
179 addrr->addr_len)) {
180 XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
181 return NB_OK; /* silent fail */
182 }
183 }
184 }
185
186 /*Forget the systemID part of the address */
187 addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
188 assert(area->area_addrs); /* to silence scan-build sillyness */
189 listnode_add(area->area_addrs, addrr);
190
191 /* only now we can safely generate our LSPs for this area */
192 if (listcount(area->area_addrs) > 0) {
193 if (area->is_type & IS_LEVEL_1)
194 lsp_generate(area, IS_LEVEL_1);
195 if (area->is_type & IS_LEVEL_2)
196 lsp_generate(area, IS_LEVEL_2);
197 }
198 break;
199 }
200
201 return NB_OK;
202 }
203
204 int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
205 {
206 struct area_addr addr, *addrp = NULL;
207 struct listnode *node;
208 uint8_t buff[255];
209 struct isis_area *area;
210 const char *net_title;
211 struct listnode *cnode;
212 struct isis_circuit *circuit;
213 int lvl;
214
215 if (args->event != NB_EV_APPLY)
216 return NB_OK;
217
218 net_title = yang_dnode_get_string(args->dnode, NULL);
219 addr.addr_len = dotformat2buff(buff, net_title);
220 memcpy(addr.area_addr, buff, (int)addr.addr_len);
221 area = nb_running_get_entry(args->dnode, NULL, true);
222
223 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
224 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
225 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
226 break;
227 }
228 if (!addrp)
229 return NB_ERR_INCONSISTENCY;
230
231 listnode_delete(area->area_addrs, addrp);
232 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
233 /*
234 * Last area address - reset the SystemID for this router
235 */
236 if (listcount(area->area_addrs) == 0) {
237 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
238 for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
239 if (circuit->u.bc.is_dr[lvl - 1])
240 isis_dr_resign(circuit, lvl);
241 }
242 memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
243 area->isis->sysid_set = 0;
244 if (IS_DEBUG_EVENTS)
245 zlog_debug("Router has no SystemID");
246 }
247
248 return NB_OK;
249 }
250
251 /*
252 * XPath: /frr-isisd:isis/instance/dynamic-hostname
253 */
254 int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args)
255 {
256 struct isis_area *area;
257
258 if (args->event != NB_EV_APPLY)
259 return NB_OK;
260
261 area = nb_running_get_entry(args->dnode, NULL, true);
262 isis_area_dynhostname_set(area, yang_dnode_get_bool(args->dnode, NULL));
263
264 return NB_OK;
265 }
266
267 /*
268 * XPath: /frr-isisd:isis/instance/attach-send
269 */
270 int isis_instance_attached_send_modify(struct nb_cb_modify_args *args)
271 {
272 struct isis_area *area;
273 bool attached;
274
275 if (args->event != NB_EV_APPLY)
276 return NB_OK;
277
278 area = nb_running_get_entry(args->dnode, NULL, true);
279 attached = yang_dnode_get_bool(args->dnode, NULL);
280 isis_area_attached_bit_send_set(area, attached);
281
282 return NB_OK;
283 }
284
285 /*
286 * XPath: /frr-isisd:isis/instance/attach-receive-ignore
287 */
288 int isis_instance_attached_receive_modify(struct nb_cb_modify_args *args)
289 {
290 struct isis_area *area;
291 bool attached;
292
293 if (args->event != NB_EV_APPLY)
294 return NB_OK;
295
296 area = nb_running_get_entry(args->dnode, NULL, true);
297 attached = yang_dnode_get_bool(args->dnode, NULL);
298 isis_area_attached_bit_receive_set(area, attached);
299
300 return NB_OK;
301 }
302
303 /*
304 * XPath: /frr-isisd:isis/instance/attached
305 */
306 int isis_instance_attached_modify(struct nb_cb_modify_args *args)
307 {
308 return NB_OK;
309 }
310
311 /*
312 * XPath: /frr-isisd:isis/instance/overload
313 */
314 int isis_instance_overload_modify(struct nb_cb_modify_args *args)
315 {
316 struct isis_area *area;
317 bool overload;
318
319 if (args->event != NB_EV_APPLY)
320 return NB_OK;
321
322 area = nb_running_get_entry(args->dnode, NULL, true);
323 overload = yang_dnode_get_bool(args->dnode, NULL);
324 isis_area_overload_bit_set(area, overload);
325
326 return NB_OK;
327 }
328
329 /*
330 * XPath: /frr-isisd:isis/instance/metric-style
331 */
332 int isis_instance_metric_style_modify(struct nb_cb_modify_args *args)
333 {
334 struct isis_area *area;
335 bool old_metric, new_metric;
336 enum isis_metric_style metric_style =
337 yang_dnode_get_enum(args->dnode, NULL);
338
339 if (args->event != NB_EV_APPLY)
340 return NB_OK;
341
342 area = nb_running_get_entry(args->dnode, NULL, true);
343 old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true;
344 new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true;
345 isis_area_metricstyle_set(area, old_metric, new_metric);
346
347 return NB_OK;
348 }
349
350 /*
351 * XPath: /frr-isisd:isis/instance/purge-originator
352 */
353 int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args)
354 {
355 struct isis_area *area;
356
357 if (args->event != NB_EV_APPLY)
358 return NB_OK;
359
360 area = nb_running_get_entry(args->dnode, NULL, true);
361 area->purge_originator = yang_dnode_get_bool(args->dnode, NULL);
362
363 return NB_OK;
364 }
365
366 /*
367 * XPath: /frr-isisd:isis/instance/lsp/mtu
368 */
369 int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args)
370 {
371 struct listnode *node;
372 struct isis_circuit *circuit;
373 uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL);
374 struct isis_area *area;
375
376 switch (args->event) {
377 case NB_EV_VALIDATE:
378 area = nb_running_get_entry(args->dnode, NULL, false);
379 if (!area)
380 break;
381 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
382 if (circuit->state != C_STATE_INIT
383 && circuit->state != C_STATE_UP)
384 continue;
385 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
386 snprintf(
387 args->errmsg, args->errmsg_len,
388 "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
389 circuit->interface->name,
390 isis_circuit_pdu_size(circuit));
391 return NB_ERR_VALIDATION;
392 }
393 }
394 break;
395 case NB_EV_PREPARE:
396 case NB_EV_ABORT:
397 break;
398 case NB_EV_APPLY:
399 area = nb_running_get_entry(args->dnode, NULL, true);
400 isis_area_lsp_mtu_set(area, lsp_mtu);
401 break;
402 }
403
404 return NB_OK;
405 }
406
407 /*
408 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval
409 */
410 int isis_instance_lsp_refresh_interval_level_1_modify(
411 struct nb_cb_modify_args *args)
412 {
413 struct isis_area *area;
414 uint16_t refr_int;
415
416 if (args->event != NB_EV_APPLY)
417 return NB_OK;
418
419 refr_int = yang_dnode_get_uint16(args->dnode, NULL);
420 area = nb_running_get_entry(args->dnode, NULL, true);
421 isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int);
422
423 return NB_OK;
424 }
425
426 /*
427 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval
428 */
429 int isis_instance_lsp_refresh_interval_level_2_modify(
430 struct nb_cb_modify_args *args)
431 {
432 struct isis_area *area;
433 uint16_t refr_int;
434
435 if (args->event != NB_EV_APPLY)
436 return NB_OK;
437
438 refr_int = yang_dnode_get_uint16(args->dnode, NULL);
439 area = nb_running_get_entry(args->dnode, NULL, true);
440 isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int);
441
442 return NB_OK;
443 }
444
445 /*
446 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime
447 */
448 int isis_instance_lsp_maximum_lifetime_level_1_modify(
449 struct nb_cb_modify_args *args)
450 {
451 struct isis_area *area;
452 uint16_t max_lt;
453
454 if (args->event != NB_EV_APPLY)
455 return NB_OK;
456
457 max_lt = yang_dnode_get_uint16(args->dnode, NULL);
458 area = nb_running_get_entry(args->dnode, NULL, true);
459 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt);
460
461 return NB_OK;
462 }
463
464 /*
465 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime
466 */
467 int isis_instance_lsp_maximum_lifetime_level_2_modify(
468 struct nb_cb_modify_args *args)
469 {
470 struct isis_area *area;
471 uint16_t max_lt;
472
473 if (args->event != NB_EV_APPLY)
474 return NB_OK;
475
476 max_lt = yang_dnode_get_uint16(args->dnode, NULL);
477 area = nb_running_get_entry(args->dnode, NULL, true);
478 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt);
479
480 return NB_OK;
481 }
482
483 /*
484 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/generation-interval
485 */
486 int isis_instance_lsp_generation_interval_level_1_modify(
487 struct nb_cb_modify_args *args)
488 {
489 struct isis_area *area;
490 uint16_t gen_int;
491
492 if (args->event != NB_EV_APPLY)
493 return NB_OK;
494
495 gen_int = yang_dnode_get_uint16(args->dnode, NULL);
496 area = nb_running_get_entry(args->dnode, NULL, true);
497 area->lsp_gen_interval[0] = gen_int;
498
499 return NB_OK;
500 }
501
502 /*
503 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/generation-interval
504 */
505 int isis_instance_lsp_generation_interval_level_2_modify(
506 struct nb_cb_modify_args *args)
507 {
508 struct isis_area *area;
509 uint16_t gen_int;
510
511 if (args->event != NB_EV_APPLY)
512 return NB_OK;
513
514 gen_int = yang_dnode_get_uint16(args->dnode, NULL);
515 area = nb_running_get_entry(args->dnode, NULL, true);
516 area->lsp_gen_interval[1] = gen_int;
517
518 return NB_OK;
519 }
520
521 /*
522 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
523 */
524 void ietf_backoff_delay_apply_finish(struct nb_cb_apply_finish_args *args)
525 {
526 long init_delay = yang_dnode_get_uint16(args->dnode, "./init-delay");
527 long short_delay = yang_dnode_get_uint16(args->dnode, "./short-delay");
528 long long_delay = yang_dnode_get_uint16(args->dnode, "./long-delay");
529 long holddown = yang_dnode_get_uint16(args->dnode, "./hold-down");
530 long timetolearn =
531 yang_dnode_get_uint16(args->dnode, "./time-to-learn");
532 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
533 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
534 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
535
536 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
537 spf_backoff_free(area->spf_delay_ietf[0]);
538 area->spf_delay_ietf[0] =
539 spf_backoff_new(master, buf, init_delay, short_delay,
540 long_delay, holddown, timetolearn);
541
542 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
543 spf_backoff_free(area->spf_delay_ietf[1]);
544 area->spf_delay_ietf[1] =
545 spf_backoff_new(master, buf, init_delay, short_delay,
546 long_delay, holddown, timetolearn);
547
548 XFREE(MTYPE_TMP, buf);
549 }
550
551 int isis_instance_spf_ietf_backoff_delay_create(struct nb_cb_create_args *args)
552 {
553 /* All the work is done in the apply_finish */
554 return NB_OK;
555 }
556
557 int isis_instance_spf_ietf_backoff_delay_destroy(
558 struct nb_cb_destroy_args *args)
559 {
560 struct isis_area *area;
561
562 if (args->event != NB_EV_APPLY)
563 return NB_OK;
564
565 area = nb_running_get_entry(args->dnode, NULL, true);
566 spf_backoff_free(area->spf_delay_ietf[0]);
567 spf_backoff_free(area->spf_delay_ietf[1]);
568 area->spf_delay_ietf[0] = NULL;
569 area->spf_delay_ietf[1] = NULL;
570
571 return NB_OK;
572 }
573
574 /*
575 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
576 */
577 int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
578 struct nb_cb_modify_args *args)
579 {
580 /* All the work is done in the apply_finish */
581 return NB_OK;
582 }
583
584 /*
585 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
586 */
587 int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
588 struct nb_cb_modify_args *args)
589 {
590 /* All the work is done in the apply_finish */
591 return NB_OK;
592 }
593
594 /*
595 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
596 */
597 int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
598 struct nb_cb_modify_args *args)
599 {
600 /* All the work is done in the apply_finish */
601 return NB_OK;
602 }
603
604 /*
605 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
606 */
607 int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
608 struct nb_cb_modify_args *args)
609 {
610 /* All the work is done in the apply_finish */
611 return NB_OK;
612 }
613
614 /*
615 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
616 */
617 int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
618 struct nb_cb_modify_args *args)
619 {
620 /* All the work is done in the apply_finish */
621 return NB_OK;
622 }
623
624 /*
625 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
626 */
627 int isis_instance_spf_minimum_interval_level_1_modify(
628 struct nb_cb_modify_args *args)
629 {
630 struct isis_area *area;
631
632 if (args->event != NB_EV_APPLY)
633 return NB_OK;
634
635 area = nb_running_get_entry(args->dnode, NULL, true);
636 area->min_spf_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
637
638 return NB_OK;
639 }
640
641 /*
642 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
643 */
644 int isis_instance_spf_minimum_interval_level_2_modify(
645 struct nb_cb_modify_args *args)
646 {
647 struct isis_area *area;
648
649 if (args->event != NB_EV_APPLY)
650 return NB_OK;
651
652 area = nb_running_get_entry(args->dnode, NULL, true);
653 area->min_spf_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
654
655 return NB_OK;
656 }
657
658 /*
659 * XPath:
660 * /frr-isisd:isis/instance/spf/prefix-priorities/critical/access-list-name
661 */
662 int isis_instance_spf_prefix_priorities_critical_access_list_name_modify(
663 struct nb_cb_modify_args *args)
664 {
665 struct isis_area *area;
666 const char *acl_name;
667 struct spf_prefix_priority_acl *ppa;
668
669 if (args->event != NB_EV_APPLY)
670 return NB_OK;
671
672 area = nb_running_get_entry(args->dnode, NULL, true);
673 acl_name = yang_dnode_get_string(args->dnode, NULL);
674
675 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_CRITICAL];
676 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
677 ppa->name = XSTRDUP(MTYPE_ISIS_ACL_NAME, acl_name);
678 ppa->list_v4 = access_list_lookup(AFI_IP, acl_name);
679 ppa->list_v6 = access_list_lookup(AFI_IP6, acl_name);
680 lsp_regenerate_schedule(area, area->is_type, 0);
681
682 return NB_OK;
683 }
684
685 int isis_instance_spf_prefix_priorities_critical_access_list_name_destroy(
686 struct nb_cb_destroy_args *args)
687 {
688 struct isis_area *area;
689 struct spf_prefix_priority_acl *ppa;
690
691 if (args->event != NB_EV_APPLY)
692 return NB_OK;
693
694 area = nb_running_get_entry(args->dnode, NULL, true);
695
696 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_CRITICAL];
697 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
698 ppa->list_v4 = NULL;
699 ppa->list_v6 = NULL;
700 lsp_regenerate_schedule(area, area->is_type, 0);
701
702 return NB_OK;
703 }
704
705 /*
706 * XPath: /frr-isisd:isis/instance/spf/prefix-priorities/high/access-list-name
707 */
708 int isis_instance_spf_prefix_priorities_high_access_list_name_modify(
709 struct nb_cb_modify_args *args)
710 {
711 struct isis_area *area;
712 const char *acl_name;
713 struct spf_prefix_priority_acl *ppa;
714
715 if (args->event != NB_EV_APPLY)
716 return NB_OK;
717
718 area = nb_running_get_entry(args->dnode, NULL, true);
719 acl_name = yang_dnode_get_string(args->dnode, NULL);
720
721 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_HIGH];
722 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
723 ppa->name = XSTRDUP(MTYPE_ISIS_ACL_NAME, acl_name);
724 ppa->list_v4 = access_list_lookup(AFI_IP, acl_name);
725 ppa->list_v6 = access_list_lookup(AFI_IP6, acl_name);
726 lsp_regenerate_schedule(area, area->is_type, 0);
727
728 return NB_OK;
729 }
730
731 int isis_instance_spf_prefix_priorities_high_access_list_name_destroy(
732 struct nb_cb_destroy_args *args)
733 {
734 struct isis_area *area;
735 struct spf_prefix_priority_acl *ppa;
736
737 if (args->event != NB_EV_APPLY)
738 return NB_OK;
739
740 area = nb_running_get_entry(args->dnode, NULL, true);
741
742 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_HIGH];
743 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
744 ppa->list_v4 = NULL;
745 ppa->list_v6 = NULL;
746 lsp_regenerate_schedule(area, area->is_type, 0);
747
748 return NB_OK;
749 }
750
751 /*
752 * XPath: /frr-isisd:isis/instance/spf/prefix-priorities/medium/access-list-name
753 */
754 int isis_instance_spf_prefix_priorities_medium_access_list_name_modify(
755 struct nb_cb_modify_args *args)
756 {
757 struct isis_area *area;
758 const char *acl_name;
759 struct spf_prefix_priority_acl *ppa;
760
761 if (args->event != NB_EV_APPLY)
762 return NB_OK;
763
764 area = nb_running_get_entry(args->dnode, NULL, true);
765 acl_name = yang_dnode_get_string(args->dnode, NULL);
766
767 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_MEDIUM];
768 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
769 ppa->name = XSTRDUP(MTYPE_ISIS_ACL_NAME, acl_name);
770 ppa->list_v4 = access_list_lookup(AFI_IP, acl_name);
771 ppa->list_v6 = access_list_lookup(AFI_IP6, acl_name);
772 lsp_regenerate_schedule(area, area->is_type, 0);
773
774 return NB_OK;
775 }
776
777 int isis_instance_spf_prefix_priorities_medium_access_list_name_destroy(
778 struct nb_cb_destroy_args *args)
779 {
780 struct isis_area *area;
781 struct spf_prefix_priority_acl *ppa;
782
783 if (args->event != NB_EV_APPLY)
784 return NB_OK;
785
786 area = nb_running_get_entry(args->dnode, NULL, true);
787
788 ppa = &area->spf_prefix_priorities[SPF_PREFIX_PRIO_MEDIUM];
789 XFREE(MTYPE_ISIS_ACL_NAME, ppa->name);
790 ppa->list_v4 = NULL;
791 ppa->list_v6 = NULL;
792 lsp_regenerate_schedule(area, area->is_type, 0);
793
794 return NB_OK;
795 }
796
797 /*
798 * XPath: /frr-isisd:isis/instance/area-password
799 */
800 void area_password_apply_finish(struct nb_cb_apply_finish_args *args)
801 {
802 const char *password = yang_dnode_get_string(args->dnode, "./password");
803 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
804 int pass_type = yang_dnode_get_enum(args->dnode, "./password-type");
805 uint8_t snp_auth =
806 yang_dnode_get_enum(args->dnode, "./authenticate-snp");
807
808 switch (pass_type) {
809 case ISIS_PASSWD_TYPE_CLEARTXT:
810 isis_area_passwd_cleartext_set(area, IS_LEVEL_1, password,
811 snp_auth);
812 break;
813 case ISIS_PASSWD_TYPE_HMAC_MD5:
814 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_1, password,
815 snp_auth);
816 break;
817 }
818 }
819
820 int isis_instance_area_password_create(struct nb_cb_create_args *args)
821 {
822 /* actual setting is done in apply_finish */
823 return NB_OK;
824 }
825
826 int isis_instance_area_password_destroy(struct nb_cb_destroy_args *args)
827 {
828 struct isis_area *area;
829
830 if (args->event != NB_EV_APPLY)
831 return NB_OK;
832
833 area = nb_running_get_entry(args->dnode, NULL, true);
834 isis_area_passwd_unset(area, IS_LEVEL_1);
835
836 return NB_OK;
837 }
838
839 /*
840 * XPath: /frr-isisd:isis/instance/area-password/password
841 */
842 int isis_instance_area_password_password_modify(struct nb_cb_modify_args *args)
843 {
844 /* actual setting is done in apply_finish */
845 return NB_OK;
846 }
847
848 /*
849 * XPath: /frr-isisd:isis/instance/area-password/password-type
850 */
851 int isis_instance_area_password_password_type_modify(
852 struct nb_cb_modify_args *args)
853 {
854 /* actual setting is done in apply_finish */
855 return NB_OK;
856 }
857
858 /*
859 * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
860 */
861 int isis_instance_area_password_authenticate_snp_modify(
862 struct nb_cb_modify_args *args)
863 {
864 /* actual setting is done in apply_finish */
865 return NB_OK;
866 }
867
868 /*
869 * XPath: /frr-isisd:isis/instance/domain-password
870 */
871 void domain_password_apply_finish(struct nb_cb_apply_finish_args *args)
872 {
873 const char *password = yang_dnode_get_string(args->dnode, "./password");
874 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
875 int pass_type = yang_dnode_get_enum(args->dnode, "./password-type");
876 uint8_t snp_auth =
877 yang_dnode_get_enum(args->dnode, "./authenticate-snp");
878
879 switch (pass_type) {
880 case ISIS_PASSWD_TYPE_CLEARTXT:
881 isis_area_passwd_cleartext_set(area, IS_LEVEL_2, password,
882 snp_auth);
883 break;
884 case ISIS_PASSWD_TYPE_HMAC_MD5:
885 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_2, password,
886 snp_auth);
887 break;
888 }
889 }
890
891 int isis_instance_domain_password_create(struct nb_cb_create_args *args)
892 {
893 /* actual setting is done in apply_finish */
894 return NB_OK;
895 }
896
897 int isis_instance_domain_password_destroy(struct nb_cb_destroy_args *args)
898 {
899 struct isis_area *area;
900
901 if (args->event != NB_EV_APPLY)
902 return NB_OK;
903
904 area = nb_running_get_entry(args->dnode, NULL, true);
905 isis_area_passwd_unset(area, IS_LEVEL_2);
906
907 return NB_OK;
908 }
909
910 /*
911 * XPath: /frr-isisd:isis/instance/domain-password/password
912 */
913 int isis_instance_domain_password_password_modify(
914 struct nb_cb_modify_args *args)
915 {
916 /* actual setting is done in apply_finish */
917 return NB_OK;
918 }
919
920 /*
921 * XPath: /frr-isisd:isis/instance/domain-password/password-type
922 */
923 int isis_instance_domain_password_password_type_modify(
924 struct nb_cb_modify_args *args)
925 {
926 /* actual setting is done in apply_finish */
927 return NB_OK;
928 }
929
930 /*
931 * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
932 */
933 int isis_instance_domain_password_authenticate_snp_modify(
934 struct nb_cb_modify_args *args)
935 {
936 /* actual setting is done in apply_finish */
937 return NB_OK;
938 }
939
940 /*
941 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
942 */
943 void default_info_origin_apply_finish(const struct lyd_node *dnode, int family)
944 {
945 int originate_type = DEFAULT_ORIGINATE;
946 unsigned long metric = 0;
947 const char *routemap = NULL;
948 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
949 int level = yang_dnode_get_enum(dnode, "./level");
950
951 if (yang_dnode_get_bool(dnode, "./always")) {
952 originate_type = DEFAULT_ORIGINATE_ALWAYS;
953 } else if (family == AF_INET6) {
954 zlog_warn(
955 "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
956 __func__);
957 }
958
959 if (yang_dnode_exists(dnode, "./metric"))
960 metric = yang_dnode_get_uint32(dnode, "./metric");
961 if (yang_dnode_exists(dnode, "./route-map"))
962 routemap = yang_dnode_get_string(dnode, "./route-map");
963
964 isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
965 originate_type);
966 }
967
968 void default_info_origin_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
969 {
970 default_info_origin_apply_finish(args->dnode, AF_INET);
971 }
972
973 void default_info_origin_ipv6_apply_finish(struct nb_cb_apply_finish_args *args)
974 {
975 default_info_origin_apply_finish(args->dnode, AF_INET6);
976 }
977
978 int isis_instance_default_information_originate_ipv4_create(
979 struct nb_cb_create_args *args)
980 {
981 /* It's all done by default_info_origin_apply_finish */
982 return NB_OK;
983 }
984
985 int isis_instance_default_information_originate_ipv4_destroy(
986 struct nb_cb_destroy_args *args)
987 {
988 struct isis_area *area;
989 int level;
990
991 if (args->event != NB_EV_APPLY)
992 return NB_OK;
993
994 area = nb_running_get_entry(args->dnode, NULL, true);
995 level = yang_dnode_get_enum(args->dnode, "./level");
996 isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
997
998 return NB_OK;
999 }
1000
1001 /*
1002 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
1003 */
1004 int isis_instance_default_information_originate_ipv4_always_modify(
1005 struct nb_cb_modify_args *args)
1006 {
1007 /* It's all done by default_info_origin_apply_finish */
1008 return NB_OK;
1009 }
1010
1011 /*
1012 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
1013 */
1014 int isis_instance_default_information_originate_ipv4_route_map_modify(
1015 struct nb_cb_modify_args *args)
1016 {
1017 /* It's all done by default_info_origin_apply_finish */
1018 return NB_OK;
1019 }
1020
1021 int isis_instance_default_information_originate_ipv4_route_map_destroy(
1022 struct nb_cb_destroy_args *args)
1023 {
1024 /* It's all done by default_info_origin_apply_finish */
1025 return NB_OK;
1026 }
1027
1028 /*
1029 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
1030 */
1031 int isis_instance_default_information_originate_ipv4_metric_modify(
1032 struct nb_cb_modify_args *args)
1033 {
1034 /* It's all done by default_info_origin_apply_finish */
1035 return NB_OK;
1036 }
1037
1038 /*
1039 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
1040 */
1041 int isis_instance_default_information_originate_ipv6_create(
1042 struct nb_cb_create_args *args)
1043 {
1044 /* It's all done by default_info_origin_apply_finish */
1045 return NB_OK;
1046 }
1047
1048 int isis_instance_default_information_originate_ipv6_destroy(
1049 struct nb_cb_destroy_args *args)
1050 {
1051 struct isis_area *area;
1052 int level;
1053
1054 if (args->event != NB_EV_APPLY)
1055 return NB_OK;
1056
1057 area = nb_running_get_entry(args->dnode, NULL, true);
1058 level = yang_dnode_get_enum(args->dnode, "./level");
1059 isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
1060
1061 return NB_OK;
1062 }
1063
1064 /*
1065 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
1066 */
1067 int isis_instance_default_information_originate_ipv6_always_modify(
1068 struct nb_cb_modify_args *args)
1069 {
1070 /* It's all done by default_info_origin_apply_finish */
1071 return NB_OK;
1072 }
1073
1074 /*
1075 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
1076 */
1077 int isis_instance_default_information_originate_ipv6_route_map_modify(
1078 struct nb_cb_modify_args *args)
1079 {
1080 /* It's all done by default_info_origin_apply_finish */
1081 return NB_OK;
1082 }
1083
1084 int isis_instance_default_information_originate_ipv6_route_map_destroy(
1085 struct nb_cb_destroy_args *args)
1086 {
1087 /* It's all done by default_info_origin_apply_finish */
1088 return NB_OK;
1089 }
1090
1091 /*
1092 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
1093 */
1094 int isis_instance_default_information_originate_ipv6_metric_modify(
1095 struct nb_cb_modify_args *args)
1096 {
1097 /* It's all done by default_info_origin_apply_finish */
1098 return NB_OK;
1099 }
1100
1101 /*
1102 * XPath: /frr-isisd:isis/instance/redistribute/ipv4
1103 */
1104 void redistribute_apply_finish(const struct lyd_node *dnode, int family)
1105 {
1106 assert(family == AF_INET || family == AF_INET6);
1107 int type, level;
1108 unsigned long metric = 0;
1109 const char *routemap = NULL;
1110 struct isis_area *area;
1111
1112 type = yang_dnode_get_enum(dnode, "./protocol");
1113 level = yang_dnode_get_enum(dnode, "./level");
1114 area = nb_running_get_entry(dnode, NULL, true);
1115
1116 if (yang_dnode_exists(dnode, "./metric"))
1117 metric = yang_dnode_get_uint32(dnode, "./metric");
1118 if (yang_dnode_exists(dnode, "./route-map"))
1119 routemap = yang_dnode_get_string(dnode, "./route-map");
1120
1121 isis_redist_set(area, level, family, type, metric, routemap, 0);
1122 }
1123
1124 void redistribute_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
1125 {
1126 redistribute_apply_finish(args->dnode, AF_INET);
1127 }
1128
1129 void redistribute_ipv6_apply_finish(struct nb_cb_apply_finish_args *args)
1130 {
1131 redistribute_apply_finish(args->dnode, AF_INET6);
1132 }
1133
1134 int isis_instance_redistribute_ipv4_create(struct nb_cb_create_args *args)
1135 {
1136 /* It's all done by redistribute_apply_finish */
1137 return NB_OK;
1138 }
1139
1140 int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args)
1141 {
1142 struct isis_area *area;
1143 int level, type;
1144
1145 if (args->event != NB_EV_APPLY)
1146 return NB_OK;
1147
1148 area = nb_running_get_entry(args->dnode, NULL, true);
1149 level = yang_dnode_get_enum(args->dnode, "./level");
1150 type = yang_dnode_get_enum(args->dnode, "./protocol");
1151 isis_redist_unset(area, level, AF_INET, type);
1152
1153 return NB_OK;
1154 }
1155
1156 /*
1157 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
1158 */
1159 int isis_instance_redistribute_ipv4_route_map_modify(
1160 struct nb_cb_modify_args *args)
1161 {
1162 /* It's all done by redistribute_apply_finish */
1163 return NB_OK;
1164 }
1165
1166 int isis_instance_redistribute_ipv4_route_map_destroy(
1167 struct nb_cb_destroy_args *args)
1168 {
1169 /* It's all done by redistribute_apply_finish */
1170 return NB_OK;
1171 }
1172
1173 /*
1174 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
1175 */
1176 int isis_instance_redistribute_ipv4_metric_modify(
1177 struct nb_cb_modify_args *args)
1178 {
1179 /* It's all done by redistribute_apply_finish */
1180 return NB_OK;
1181 }
1182
1183 /*
1184 * XPath: /frr-isisd:isis/instance/redistribute/ipv6
1185 */
1186 int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args)
1187 {
1188 /* It's all done by redistribute_apply_finish */
1189 return NB_OK;
1190 }
1191
1192 int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args)
1193 {
1194 struct isis_area *area;
1195 int level, type;
1196
1197 if (args->event != NB_EV_APPLY)
1198 return NB_OK;
1199
1200 area = nb_running_get_entry(args->dnode, NULL, true);
1201 level = yang_dnode_get_enum(args->dnode, "./level");
1202 type = yang_dnode_get_enum(args->dnode, "./protocol");
1203 isis_redist_unset(area, level, AF_INET6, type);
1204
1205 return NB_OK;
1206 }
1207
1208 /*
1209 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
1210 */
1211 int isis_instance_redistribute_ipv6_route_map_modify(
1212 struct nb_cb_modify_args *args)
1213 {
1214 /* It's all done by redistribute_apply_finish */
1215 return NB_OK;
1216 }
1217
1218 int isis_instance_redistribute_ipv6_route_map_destroy(
1219 struct nb_cb_destroy_args *args)
1220 {
1221 /* It's all done by redistribute_apply_finish */
1222 return NB_OK;
1223 }
1224
1225 /*
1226 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
1227 */
1228 int isis_instance_redistribute_ipv6_metric_modify(
1229 struct nb_cb_modify_args *args)
1230 {
1231 /* It's all done by redistribute_apply_finish */
1232 return NB_OK;
1233 }
1234
1235 /*
1236 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
1237 */
1238 static int isis_multi_topology_common(enum nb_event event,
1239 const struct lyd_node *dnode,
1240 char *errmsg, size_t errmsg_len,
1241 const char *topology, bool create)
1242 {
1243 struct isis_area *area;
1244 struct isis_area_mt_setting *setting;
1245 uint16_t mtid = isis_str2mtid(topology);
1246
1247 switch (event) {
1248 case NB_EV_VALIDATE:
1249 if (mtid == (uint16_t)-1) {
1250 snprintf(errmsg, errmsg_len, "Unknown topology %s",
1251 topology);
1252 return NB_ERR_VALIDATION;
1253 }
1254 break;
1255 case NB_EV_PREPARE:
1256 case NB_EV_ABORT:
1257 break;
1258 case NB_EV_APPLY:
1259 area = nb_running_get_entry(dnode, NULL, true);
1260 setting = area_get_mt_setting(area, mtid);
1261 setting->enabled = create;
1262 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1263 break;
1264 }
1265
1266 return NB_OK;
1267 }
1268
1269 static int isis_multi_topology_overload_common(enum nb_event event,
1270 const struct lyd_node *dnode,
1271 const char *topology)
1272 {
1273 struct isis_area *area;
1274 struct isis_area_mt_setting *setting;
1275 uint16_t mtid = isis_str2mtid(topology);
1276
1277 /* validation is done in isis_multi_topology_common */
1278 if (event != NB_EV_APPLY)
1279 return NB_OK;
1280
1281 area = nb_running_get_entry(dnode, NULL, true);
1282 setting = area_get_mt_setting(area, mtid);
1283 setting->overload = yang_dnode_get_bool(dnode, NULL);
1284 if (setting->enabled)
1285 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1286
1287 return NB_OK;
1288 }
1289
1290 int isis_instance_multi_topology_ipv4_multicast_create(
1291 struct nb_cb_create_args *args)
1292 {
1293 return isis_multi_topology_common(args->event, args->dnode,
1294 args->errmsg, args->errmsg_len,
1295 "ipv4-multicast", true);
1296 }
1297
1298 int isis_instance_multi_topology_ipv4_multicast_destroy(
1299 struct nb_cb_destroy_args *args)
1300 {
1301 return isis_multi_topology_common(args->event, args->dnode,
1302 args->errmsg, args->errmsg_len,
1303 "ipv4-multicast", false);
1304 }
1305
1306 /*
1307 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
1308 */
1309 int isis_instance_multi_topology_ipv4_multicast_overload_modify(
1310 struct nb_cb_modify_args *args)
1311 {
1312 return isis_multi_topology_overload_common(args->event, args->dnode,
1313 "ipv4-multicast");
1314 }
1315
1316 /*
1317 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
1318 */
1319 int isis_instance_multi_topology_ipv4_management_create(
1320 struct nb_cb_create_args *args)
1321 {
1322 return isis_multi_topology_common(args->event, args->dnode,
1323 args->errmsg, args->errmsg_len,
1324 "ipv4-mgmt", true);
1325 }
1326
1327 int isis_instance_multi_topology_ipv4_management_destroy(
1328 struct nb_cb_destroy_args *args)
1329 {
1330 return isis_multi_topology_common(args->event, args->dnode,
1331 args->errmsg, args->errmsg_len,
1332 "ipv4-mgmt", false);
1333 }
1334
1335 /*
1336 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
1337 */
1338 int isis_instance_multi_topology_ipv4_management_overload_modify(
1339 struct nb_cb_modify_args *args)
1340 {
1341 return isis_multi_topology_overload_common(args->event, args->dnode,
1342 "ipv4-mgmt");
1343 }
1344
1345 /*
1346 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
1347 */
1348 int isis_instance_multi_topology_ipv6_unicast_create(
1349 struct nb_cb_create_args *args)
1350 {
1351 return isis_multi_topology_common(args->event, args->dnode,
1352 args->errmsg, args->errmsg_len,
1353 "ipv6-unicast", true);
1354 }
1355
1356 int isis_instance_multi_topology_ipv6_unicast_destroy(
1357 struct nb_cb_destroy_args *args)
1358 {
1359 return isis_multi_topology_common(args->event, args->dnode,
1360 args->errmsg, args->errmsg_len,
1361 "ipv6-unicast", false);
1362 }
1363
1364 /*
1365 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
1366 */
1367 int isis_instance_multi_topology_ipv6_unicast_overload_modify(
1368 struct nb_cb_modify_args *args)
1369 {
1370 return isis_multi_topology_overload_common(args->event, args->dnode,
1371 "ipv6-unicast");
1372 }
1373
1374 /*
1375 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
1376 */
1377 int isis_instance_multi_topology_ipv6_multicast_create(
1378 struct nb_cb_create_args *args)
1379 {
1380 return isis_multi_topology_common(args->event, args->dnode,
1381 args->errmsg, args->errmsg_len,
1382 "ipv6-multicast", true);
1383 }
1384
1385 int isis_instance_multi_topology_ipv6_multicast_destroy(
1386 struct nb_cb_destroy_args *args)
1387 {
1388 return isis_multi_topology_common(args->event, args->dnode,
1389 args->errmsg, args->errmsg_len,
1390 "ipv6-multicast", false);
1391 }
1392
1393 /*
1394 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
1395 */
1396 int isis_instance_multi_topology_ipv6_multicast_overload_modify(
1397 struct nb_cb_modify_args *args)
1398 {
1399 return isis_multi_topology_overload_common(args->event, args->dnode,
1400 "ipv6-multicast");
1401 }
1402
1403 /*
1404 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
1405 */
1406 int isis_instance_multi_topology_ipv6_management_create(
1407 struct nb_cb_create_args *args)
1408 {
1409 return isis_multi_topology_common(args->event, args->dnode,
1410 args->errmsg, args->errmsg_len,
1411 "ipv6-mgmt", true);
1412 }
1413
1414 int isis_instance_multi_topology_ipv6_management_destroy(
1415 struct nb_cb_destroy_args *args)
1416 {
1417 return isis_multi_topology_common(args->event, args->dnode,
1418 args->errmsg, args->errmsg_len,
1419 "ipv6-mgmt", false);
1420 }
1421
1422 /*
1423 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
1424 */
1425 int isis_instance_multi_topology_ipv6_management_overload_modify(
1426 struct nb_cb_modify_args *args)
1427 {
1428 return isis_multi_topology_overload_common(args->event, args->dnode,
1429 "ipv6-mgmt");
1430 }
1431
1432 /*
1433 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
1434 */
1435 int isis_instance_multi_topology_ipv6_dstsrc_create(
1436 struct nb_cb_create_args *args)
1437 {
1438 return isis_multi_topology_common(args->event, args->dnode,
1439 args->errmsg, args->errmsg_len,
1440 "ipv6-dstsrc", true);
1441 }
1442
1443 int isis_instance_multi_topology_ipv6_dstsrc_destroy(
1444 struct nb_cb_destroy_args *args)
1445 {
1446 return isis_multi_topology_common(args->event, args->dnode,
1447 args->errmsg, args->errmsg_len,
1448 "ipv6-dstsrc", false);
1449 }
1450
1451 /*
1452 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
1453 */
1454 int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
1455 struct nb_cb_modify_args *args)
1456 {
1457 return isis_multi_topology_overload_common(args->event, args->dnode,
1458 "ipv6-dstsrc");
1459 }
1460
1461 /*
1462 * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing
1463 */
1464 int isis_instance_fast_reroute_level_1_lfa_load_sharing_modify(
1465 struct nb_cb_modify_args *args)
1466 {
1467 struct isis_area *area;
1468
1469 if (args->event != NB_EV_APPLY)
1470 return NB_OK;
1471
1472 area = nb_running_get_entry(args->dnode, NULL, true);
1473 area->lfa_load_sharing[0] = yang_dnode_get_bool(args->dnode, NULL);
1474 lsp_regenerate_schedule(area, area->is_type, 0);
1475
1476 return NB_OK;
1477 }
1478
1479 /*
1480 * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/lfa/priority-limit
1481 */
1482 int isis_instance_fast_reroute_level_1_lfa_priority_limit_modify(
1483 struct nb_cb_modify_args *args)
1484 {
1485 struct isis_area *area;
1486
1487 if (args->event != NB_EV_APPLY)
1488 return NB_OK;
1489
1490 area = nb_running_get_entry(args->dnode, NULL, true);
1491 area->lfa_priority_limit[0] = yang_dnode_get_enum(args->dnode, NULL);
1492 lsp_regenerate_schedule(area, area->is_type, 0);
1493
1494 return NB_OK;
1495 }
1496
1497 int isis_instance_fast_reroute_level_1_lfa_priority_limit_destroy(
1498 struct nb_cb_destroy_args *args)
1499 {
1500 struct isis_area *area;
1501
1502 if (args->event != NB_EV_APPLY)
1503 return NB_OK;
1504
1505 area = nb_running_get_entry(args->dnode, NULL, true);
1506 area->lfa_priority_limit[0] = SPF_PREFIX_PRIO_LOW;
1507 lsp_regenerate_schedule(area, area->is_type, 0);
1508
1509 return NB_OK;
1510 }
1511
1512 /*
1513 * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/lfa/tiebreaker
1514 */
1515 int isis_instance_fast_reroute_level_1_lfa_tiebreaker_create(
1516 struct nb_cb_create_args *args)
1517 {
1518 struct isis_area *area;
1519 uint8_t index;
1520 enum lfa_tiebreaker_type type;
1521 struct lfa_tiebreaker *tie_b;
1522
1523 if (args->event != NB_EV_APPLY)
1524 return NB_OK;
1525
1526 area = nb_running_get_entry(args->dnode, NULL, true);
1527 index = yang_dnode_get_uint8(args->dnode, "./index");
1528 type = yang_dnode_get_enum(args->dnode, "./type");
1529
1530 tie_b = isis_lfa_tiebreaker_add(area, ISIS_LEVEL1, index, type);
1531 nb_running_set_entry(args->dnode, tie_b);
1532 lsp_regenerate_schedule(area, area->is_type, 0);
1533
1534 return NB_OK;
1535 }
1536
1537 int isis_instance_fast_reroute_level_1_lfa_tiebreaker_destroy(
1538 struct nb_cb_destroy_args *args)
1539 {
1540 struct lfa_tiebreaker *tie_b;
1541 struct isis_area *area;
1542
1543 if (args->event != NB_EV_APPLY)
1544 return NB_OK;
1545
1546 tie_b = nb_running_unset_entry(args->dnode);
1547 area = tie_b->area;
1548 isis_lfa_tiebreaker_delete(area, ISIS_LEVEL1, tie_b);
1549 lsp_regenerate_schedule(area, area->is_type, 0);
1550
1551 return NB_OK;
1552 }
1553
1554 /*
1555 * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/lfa/tiebreaker/type
1556 */
1557 int isis_instance_fast_reroute_level_1_lfa_tiebreaker_type_modify(
1558 struct nb_cb_modify_args *args)
1559 {
1560 struct lfa_tiebreaker *tie_b;
1561 struct isis_area *area;
1562
1563 if (args->event != NB_EV_APPLY)
1564 return NB_OK;
1565
1566 tie_b = nb_running_get_entry(args->dnode, NULL, true);
1567 area = tie_b->area;
1568 tie_b->type = yang_dnode_get_enum(args->dnode, NULL);
1569 lsp_regenerate_schedule(area, area->is_type, 0);
1570
1571 return NB_OK;
1572 }
1573
1574 /*
1575 * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/remote-lfa/prefix-list
1576 */
1577 int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_modify(
1578 struct nb_cb_modify_args *args)
1579 {
1580 struct isis_area *area;
1581 const char *plist_name;
1582
1583 if (args->event != NB_EV_APPLY)
1584 return NB_OK;
1585
1586 area = nb_running_get_entry(args->dnode, NULL, true);
1587 plist_name = yang_dnode_get_string(args->dnode, NULL);
1588
1589 area->rlfa_plist_name[0] = XSTRDUP(MTYPE_ISIS_PLIST_NAME, plist_name);
1590 area->rlfa_plist[0] = prefix_list_lookup(AFI_IP, plist_name);
1591 lsp_regenerate_schedule(area, area->is_type, 0);
1592
1593 return NB_OK;
1594 }
1595
1596 int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_destroy(
1597 struct nb_cb_destroy_args *args)
1598 {
1599 struct isis_area *area;
1600
1601 if (args->event != NB_EV_APPLY)
1602 return NB_OK;
1603
1604 area = nb_running_get_entry(args->dnode, NULL, true);
1605
1606 XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[0]);
1607 area->rlfa_plist[0] = NULL;
1608 lsp_regenerate_schedule(area, area->is_type, 0);
1609
1610 return NB_OK;
1611 }
1612
1613 /*
1614 * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing
1615 */
1616 int isis_instance_fast_reroute_level_2_lfa_load_sharing_modify(
1617 struct nb_cb_modify_args *args)
1618 {
1619 struct isis_area *area;
1620
1621 if (args->event != NB_EV_APPLY)
1622 return NB_OK;
1623
1624 area = nb_running_get_entry(args->dnode, NULL, true);
1625 area->lfa_load_sharing[1] = yang_dnode_get_bool(args->dnode, NULL);
1626
1627 return NB_OK;
1628 }
1629
1630 /*
1631 * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/lfa/priority-limit
1632 */
1633 int isis_instance_fast_reroute_level_2_lfa_priority_limit_modify(
1634 struct nb_cb_modify_args *args)
1635 {
1636 struct isis_area *area;
1637
1638 if (args->event != NB_EV_APPLY)
1639 return NB_OK;
1640
1641 area = nb_running_get_entry(args->dnode, NULL, true);
1642 area->lfa_priority_limit[1] = yang_dnode_get_enum(args->dnode, NULL);
1643
1644 return NB_OK;
1645 }
1646
1647 int isis_instance_fast_reroute_level_2_lfa_priority_limit_destroy(
1648 struct nb_cb_destroy_args *args)
1649 {
1650 struct isis_area *area;
1651
1652 if (args->event != NB_EV_APPLY)
1653 return NB_OK;
1654
1655 area = nb_running_get_entry(args->dnode, NULL, true);
1656 area->lfa_priority_limit[1] = SPF_PREFIX_PRIO_LOW;
1657
1658 return NB_OK;
1659 }
1660
1661 /*
1662 * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/lfa/tiebreaker
1663 */
1664 int isis_instance_fast_reroute_level_2_lfa_tiebreaker_create(
1665 struct nb_cb_create_args *args)
1666 {
1667 struct isis_area *area;
1668 uint8_t index;
1669 enum lfa_tiebreaker_type type;
1670 struct lfa_tiebreaker *tie_b;
1671
1672 if (args->event != NB_EV_APPLY)
1673 return NB_OK;
1674
1675 area = nb_running_get_entry(args->dnode, NULL, true);
1676 index = yang_dnode_get_uint8(args->dnode, "./index");
1677 type = yang_dnode_get_enum(args->dnode, "./type");
1678
1679 tie_b = isis_lfa_tiebreaker_add(area, ISIS_LEVEL2, index, type);
1680 nb_running_set_entry(args->dnode, tie_b);
1681 lsp_regenerate_schedule(area, area->is_type, 0);
1682
1683 return NB_OK;
1684 }
1685
1686 int isis_instance_fast_reroute_level_2_lfa_tiebreaker_destroy(
1687 struct nb_cb_destroy_args *args)
1688 {
1689 struct lfa_tiebreaker *tie_b;
1690 struct isis_area *area;
1691
1692 if (args->event != NB_EV_APPLY)
1693 return NB_OK;
1694
1695 tie_b = nb_running_unset_entry(args->dnode);
1696 area = tie_b->area;
1697 isis_lfa_tiebreaker_delete(area, ISIS_LEVEL2, tie_b);
1698 lsp_regenerate_schedule(area, area->is_type, 0);
1699
1700 return NB_OK;
1701 }
1702
1703 /*
1704 * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/lfa/tiebreaker/type
1705 */
1706 int isis_instance_fast_reroute_level_2_lfa_tiebreaker_type_modify(
1707 struct nb_cb_modify_args *args)
1708 {
1709 struct lfa_tiebreaker *tie_b;
1710 struct isis_area *area;
1711
1712 if (args->event != NB_EV_APPLY)
1713 return NB_OK;
1714
1715 tie_b = nb_running_get_entry(args->dnode, NULL, true);
1716 area = tie_b->area;
1717 tie_b->type = yang_dnode_get_enum(args->dnode, NULL);
1718 lsp_regenerate_schedule(area, area->is_type, 0);
1719
1720 return NB_OK;
1721 }
1722
1723 /*
1724 * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/remote-lfa/prefix-list
1725 */
1726 int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify(
1727 struct nb_cb_modify_args *args)
1728 {
1729 struct isis_area *area;
1730 const char *plist_name;
1731
1732 if (args->event != NB_EV_APPLY)
1733 return NB_OK;
1734
1735 area = nb_running_get_entry(args->dnode, NULL, true);
1736 plist_name = yang_dnode_get_string(args->dnode, NULL);
1737
1738 area->rlfa_plist_name[1] = XSTRDUP(MTYPE_ISIS_PLIST_NAME, plist_name);
1739 area->rlfa_plist[1] = prefix_list_lookup(AFI_IP, plist_name);
1740 lsp_regenerate_schedule(area, area->is_type, 0);
1741
1742 return NB_OK;
1743 }
1744
1745 int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy(
1746 struct nb_cb_destroy_args *args)
1747 {
1748 struct isis_area *area;
1749
1750 if (args->event != NB_EV_APPLY)
1751 return NB_OK;
1752
1753 area = nb_running_get_entry(args->dnode, NULL, true);
1754
1755 XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[1]);
1756 area->rlfa_plist[1] = NULL;
1757 lsp_regenerate_schedule(area, area->is_type, 0);
1758
1759 return NB_OK;
1760 }
1761
1762 /*
1763 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1764 */
1765 int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args)
1766 {
1767 struct isis_area *area;
1768 bool log = yang_dnode_get_bool(args->dnode, NULL);
1769
1770 if (args->event != NB_EV_APPLY)
1771 return NB_OK;
1772
1773 area = nb_running_get_entry(args->dnode, NULL, true);
1774 area->log_adj_changes = log ? 1 : 0;
1775
1776 return NB_OK;
1777 }
1778
1779 /*
1780 * XPath: /frr-isisd:isis/instance/mpls-te
1781 */
1782 int isis_instance_mpls_te_create(struct nb_cb_create_args *args)
1783 {
1784 struct listnode *node;
1785 struct isis_area *area;
1786 struct isis_circuit *circuit;
1787
1788 if (args->event != NB_EV_APPLY)
1789 return NB_OK;
1790
1791 area = nb_running_get_entry(args->dnode, NULL, true);
1792 if (area->mta == NULL) {
1793
1794 struct mpls_te_area *new;
1795
1796 zlog_debug("ISIS-TE(%s): Initialize MPLS Traffic Engineering",
1797 area->area_tag);
1798
1799 new = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_area));
1800
1801 /* Initialize MPLS_TE structure */
1802 new->status = enable;
1803 new->level = 0;
1804 new->inter_as = off;
1805 new->interas_areaid.s_addr = 0;
1806 new->router_id.s_addr = 0;
1807
1808 area->mta = new;
1809 } else {
1810 area->mta->status = enable;
1811 }
1812
1813 /* Update Extended TLVs according to Interface link parameters */
1814 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
1815 isis_link_params_update(circuit, circuit->interface);
1816
1817 /* Reoriginate STD_TE & GMPLS circuits */
1818 lsp_regenerate_schedule(area, area->is_type, 0);
1819
1820 return NB_OK;
1821 }
1822
1823 int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args)
1824 {
1825 struct listnode *node;
1826 struct isis_area *area;
1827 struct isis_circuit *circuit;
1828
1829 if (args->event != NB_EV_APPLY)
1830 return NB_OK;
1831
1832 area = nb_running_get_entry(args->dnode, NULL, true);
1833 if (IS_MPLS_TE(area->mta))
1834 area->mta->status = disable;
1835 else
1836 return NB_OK;
1837
1838 /* Flush LSP if circuit engage */
1839 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
1840 if (!IS_EXT_TE(circuit->ext))
1841 continue;
1842
1843 /* disable MPLS_TE Circuit keeping SR one's */
1844 if (IS_SUBTLV(circuit->ext, EXT_ADJ_SID))
1845 circuit->ext->status = EXT_ADJ_SID;
1846 else if (IS_SUBTLV(circuit->ext, EXT_LAN_ADJ_SID))
1847 circuit->ext->status = EXT_LAN_ADJ_SID;
1848 else
1849 circuit->ext->status = 0;
1850 }
1851
1852 /* Reoriginate STD_TE & GMPLS circuits */
1853 lsp_regenerate_schedule(area, area->is_type, 0);
1854
1855 zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
1856 area->area_tag);
1857
1858 return NB_OK;
1859 }
1860
1861 /*
1862 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
1863 */
1864 int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args)
1865 {
1866 struct in_addr value;
1867 struct isis_area *area;
1868
1869 if (args->event != NB_EV_APPLY)
1870 return NB_OK;
1871
1872 area = nb_running_get_entry(args->dnode, NULL, true);
1873 /* only proceed if MPLS-TE is enabled */
1874 if (!IS_MPLS_TE(area->mta))
1875 return NB_OK;
1876
1877 /* Update Area Router ID */
1878 yang_dnode_get_ipv4(&value, args->dnode, NULL);
1879 area->mta->router_id.s_addr = value.s_addr;
1880
1881 /* And re-schedule LSP update */
1882 lsp_regenerate_schedule(area, area->is_type, 0);
1883
1884 return NB_OK;
1885 }
1886
1887 int isis_instance_mpls_te_router_address_destroy(
1888 struct nb_cb_destroy_args *args)
1889 {
1890 struct isis_area *area;
1891
1892 if (args->event != NB_EV_APPLY)
1893 return NB_OK;
1894
1895 area = nb_running_get_entry(args->dnode, NULL, true);
1896 /* only proceed if MPLS-TE is enabled */
1897 if (!IS_MPLS_TE(area->mta))
1898 return NB_OK;
1899
1900 /* Reset Area Router ID */
1901 area->mta->router_id.s_addr = INADDR_ANY;
1902
1903 /* And re-schedule LSP update */
1904 lsp_regenerate_schedule(area, area->is_type, 0);
1905
1906 return NB_OK;
1907 }
1908
1909 /*
1910 * XPath: /frr-isisd:isis/instance/segment-routing/enabled
1911 */
1912 int isis_instance_segment_routing_enabled_modify(
1913 struct nb_cb_modify_args *args)
1914 {
1915 struct isis_area *area;
1916
1917 if (args->event != NB_EV_APPLY)
1918 return NB_OK;
1919
1920 area = nb_running_get_entry(args->dnode, NULL, true);
1921 area->srdb.config.enabled = yang_dnode_get_bool(args->dnode, NULL);
1922
1923 if (area->srdb.config.enabled) {
1924 if (IS_DEBUG_EVENTS)
1925 zlog_debug("SR: Segment Routing: OFF -> ON");
1926
1927 isis_sr_start(area);
1928 } else {
1929 if (IS_DEBUG_EVENTS)
1930 zlog_debug("SR: Segment Routing: ON -> OFF");
1931
1932 isis_sr_stop(area);
1933 }
1934
1935 return NB_OK;
1936 }
1937
1938 /*
1939 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks
1940 */
1941 int isis_instance_segment_routing_label_blocks_pre_validate(
1942 struct nb_cb_pre_validate_args *args)
1943 {
1944 uint32_t srgb_lbound;
1945 uint32_t srgb_ubound;
1946 uint32_t srlb_lbound;
1947 uint32_t srlb_ubound;
1948
1949 srgb_lbound = yang_dnode_get_uint32(args->dnode, "./srgb/lower-bound");
1950 srgb_ubound = yang_dnode_get_uint32(args->dnode, "./srgb/upper-bound");
1951 srlb_lbound = yang_dnode_get_uint32(args->dnode, "./srlb/lower-bound");
1952 srlb_ubound = yang_dnode_get_uint32(args->dnode, "./srlb/upper-bound");
1953
1954 /* Check that the block size does not exceed 65535 */
1955 if ((srgb_ubound - srgb_lbound + 1) > 65535) {
1956 snprintf(
1957 args->errmsg, args->errmsg_len,
1958 "New SR Global Block (%u/%u) exceed the limit of 65535",
1959 srgb_lbound, srgb_ubound);
1960 return NB_ERR_VALIDATION;
1961 }
1962 if ((srlb_ubound - srlb_lbound + 1) > 65535) {
1963 snprintf(args->errmsg, args->errmsg_len,
1964 "New SR Local Block (%u/%u) exceed the limit of 65535",
1965 srlb_lbound, srlb_ubound);
1966 return NB_ERR_VALIDATION;
1967 }
1968
1969 /* Validate SRGB against SRLB */
1970 if (!((srgb_ubound < srlb_lbound) || (srgb_lbound > srlb_ubound))) {
1971 snprintf(
1972 args->errmsg, args->errmsg_len,
1973 "SR Global Block (%u/%u) conflicts with Local Block (%u/%u)",
1974 srgb_lbound, srgb_ubound, srlb_lbound, srlb_ubound);
1975 return NB_ERR_VALIDATION;
1976 }
1977
1978 return NB_OK;
1979 }
1980
1981 /*
1982 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srgb
1983 */
1984
1985 void isis_instance_segment_routing_srgb_apply_finish(
1986 struct nb_cb_apply_finish_args *args)
1987 {
1988 struct isis_area *area;
1989 uint32_t lower_bound, upper_bound;
1990
1991 area = nb_running_get_entry(args->dnode, NULL, true);
1992 lower_bound = yang_dnode_get_uint32(args->dnode, "./lower-bound");
1993 upper_bound = yang_dnode_get_uint32(args->dnode, "./upper-bound");
1994
1995 isis_sr_cfg_srgb_update(area, lower_bound, upper_bound);
1996 }
1997
1998 /*
1999 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srgb/lower-bound
2000 */
2001 int isis_instance_segment_routing_srgb_lower_bound_modify(
2002 struct nb_cb_modify_args *args)
2003 {
2004 uint32_t lower_bound = yang_dnode_get_uint32(args->dnode, NULL);
2005
2006 switch (args->event) {
2007 case NB_EV_VALIDATE:
2008 if (!IS_MPLS_UNRESERVED_LABEL(lower_bound)) {
2009 snprintf(args->errmsg, args->errmsg_len,
2010 "Invalid SRGB lower bound: %u", lower_bound);
2011 return NB_ERR_VALIDATION;
2012 }
2013 break;
2014 case NB_EV_PREPARE:
2015 case NB_EV_ABORT:
2016 case NB_EV_APPLY:
2017 break;
2018 }
2019
2020 return NB_OK;
2021 }
2022
2023 /*
2024 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srgb/upper-bound
2025 */
2026 int isis_instance_segment_routing_srgb_upper_bound_modify(
2027 struct nb_cb_modify_args *args)
2028 {
2029 uint32_t upper_bound = yang_dnode_get_uint32(args->dnode, NULL);
2030
2031 switch (args->event) {
2032 case NB_EV_VALIDATE:
2033 if (!IS_MPLS_UNRESERVED_LABEL(upper_bound)) {
2034 snprintf(args->errmsg, args->errmsg_len,
2035 "Invalid SRGB upper bound: %u", upper_bound);
2036 return NB_ERR_VALIDATION;
2037 }
2038 break;
2039 case NB_EV_PREPARE:
2040 case NB_EV_ABORT:
2041 case NB_EV_APPLY:
2042 break;
2043 }
2044
2045 return NB_OK;
2046 }
2047
2048 /*
2049 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srlb
2050 */
2051 void isis_instance_segment_routing_srlb_apply_finish(
2052 struct nb_cb_apply_finish_args *args)
2053 {
2054 struct isis_area *area;
2055 uint32_t lower_bound, upper_bound;
2056
2057 area = nb_running_get_entry(args->dnode, NULL, true);
2058 lower_bound = yang_dnode_get_uint32(args->dnode, "./lower-bound");
2059 upper_bound = yang_dnode_get_uint32(args->dnode, "./upper-bound");
2060
2061 isis_sr_cfg_srlb_update(area, lower_bound, upper_bound);
2062 }
2063
2064 /*
2065 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srlb/lower-bound
2066 */
2067 int isis_instance_segment_routing_srlb_lower_bound_modify(
2068 struct nb_cb_modify_args *args)
2069 {
2070 uint32_t lower_bound = yang_dnode_get_uint32(args->dnode, NULL);
2071
2072 switch (args->event) {
2073 case NB_EV_VALIDATE:
2074 if (!IS_MPLS_UNRESERVED_LABEL(lower_bound)) {
2075 snprintf(args->errmsg, args->errmsg_len,
2076 "Invalid SRLB lower bound: %u", lower_bound);
2077 return NB_ERR_VALIDATION;
2078 }
2079 break;
2080 case NB_EV_PREPARE:
2081 case NB_EV_ABORT:
2082 case NB_EV_APPLY:
2083 break;
2084 }
2085
2086 return NB_OK;
2087 }
2088
2089 /*
2090 * XPath: /frr-isisd:isis/instance/segment-routing/label-blocks/srlb/upper-bound
2091 */
2092 int isis_instance_segment_routing_srlb_upper_bound_modify(
2093 struct nb_cb_modify_args *args)
2094 {
2095 uint32_t upper_bound = yang_dnode_get_uint32(args->dnode, NULL);
2096
2097 switch (args->event) {
2098 case NB_EV_VALIDATE:
2099 if (!IS_MPLS_UNRESERVED_LABEL(upper_bound)) {
2100 snprintf(args->errmsg, args->errmsg_len,
2101 "Invalid SRLB upper bound: %u", upper_bound);
2102 return NB_ERR_VALIDATION;
2103 }
2104 break;
2105 case NB_EV_PREPARE:
2106 case NB_EV_ABORT:
2107 case NB_EV_APPLY:
2108 break;
2109 }
2110
2111 return NB_OK;
2112 }
2113
2114 /*
2115 * XPath: /frr-isisd:isis/instance/segment-routing/msd/node-msd
2116 */
2117 int isis_instance_segment_routing_msd_node_msd_modify(
2118 struct nb_cb_modify_args *args)
2119 {
2120 struct isis_area *area;
2121
2122 if (args->event != NB_EV_APPLY)
2123 return NB_OK;
2124
2125 area = nb_running_get_entry(args->dnode, NULL, true);
2126 area->srdb.config.msd = yang_dnode_get_uint8(args->dnode, NULL);
2127
2128 /* Update and regenerate LSP */
2129 lsp_regenerate_schedule(area, area->is_type, 0);
2130
2131 return NB_OK;
2132 }
2133
2134 int isis_instance_segment_routing_msd_node_msd_destroy(
2135 struct nb_cb_destroy_args *args)
2136 {
2137 struct isis_area *area;
2138
2139 if (args->event != NB_EV_APPLY)
2140 return NB_OK;
2141
2142 area = nb_running_get_entry(args->dnode, NULL, true);
2143 area->srdb.config.msd = 0;
2144
2145 /* Update and regenerate LSP */
2146 lsp_regenerate_schedule(area, area->is_type, 0);
2147
2148 return NB_OK;
2149 }
2150
2151 /*
2152 * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid
2153 */
2154 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_create(
2155 struct nb_cb_create_args *args)
2156 {
2157 struct isis_area *area;
2158 struct prefix prefix;
2159 struct sr_prefix_cfg *pcfg;
2160
2161 if (args->event != NB_EV_APPLY)
2162 return NB_OK;
2163
2164 area = nb_running_get_entry(args->dnode, NULL, true);
2165 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
2166
2167 pcfg = isis_sr_cfg_prefix_add(area, &prefix);
2168 nb_running_set_entry(args->dnode, pcfg);
2169
2170 return NB_OK;
2171 }
2172
2173 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_destroy(
2174 struct nb_cb_destroy_args *args)
2175 {
2176 struct sr_prefix_cfg *pcfg;
2177 struct isis_area *area;
2178
2179 if (args->event != NB_EV_APPLY)
2180 return NB_OK;
2181
2182 pcfg = nb_running_unset_entry(args->dnode);
2183 area = pcfg->area;
2184 isis_sr_cfg_prefix_del(pcfg);
2185 lsp_regenerate_schedule(area, area->is_type, 0);
2186
2187 return NB_OK;
2188 }
2189
2190 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_pre_validate(
2191 struct nb_cb_pre_validate_args *args)
2192 {
2193 const struct lyd_node *area_dnode;
2194 struct isis_area *area;
2195 struct prefix prefix;
2196 uint32_t srgb_lbound;
2197 uint32_t srgb_ubound;
2198 uint32_t srgb_range;
2199 uint32_t sid;
2200 enum sr_sid_value_type sid_type;
2201 struct isis_prefix_sid psid = {};
2202
2203 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
2204 srgb_lbound = yang_dnode_get_uint32(
2205 args->dnode, "../../label-blocks/srgb/lower-bound");
2206 srgb_ubound = yang_dnode_get_uint32(
2207 args->dnode, "../../label-blocks/srgb/upper-bound");
2208 sid = yang_dnode_get_uint32(args->dnode, "./sid-value");
2209 sid_type = yang_dnode_get_enum(args->dnode, "./sid-value-type");
2210
2211 /* Check for invalid indexes/labels. */
2212 srgb_range = srgb_ubound - srgb_lbound + 1;
2213 psid.value = sid;
2214 switch (sid_type) {
2215 case SR_SID_VALUE_TYPE_INDEX:
2216 if (sid >= srgb_range) {
2217 snprintf(args->errmsg, args->errmsg_len,
2218 "SID index %u falls outside local SRGB range",
2219 sid);
2220 return NB_ERR_VALIDATION;
2221 }
2222 break;
2223 case SR_SID_VALUE_TYPE_ABSOLUTE:
2224 if (!IS_MPLS_UNRESERVED_LABEL(sid)) {
2225 snprintf(args->errmsg, args->errmsg_len,
2226 "Invalid absolute SID %u", sid);
2227 return NB_ERR_VALIDATION;
2228 }
2229 SET_FLAG(psid.flags, ISIS_PREFIX_SID_VALUE);
2230 SET_FLAG(psid.flags, ISIS_PREFIX_SID_LOCAL);
2231 break;
2232 }
2233
2234 /* Check for Prefix-SID collisions. */
2235 area_dnode = yang_dnode_get_parent(args->dnode, "instance");
2236 area = nb_running_get_entry(area_dnode, NULL, false);
2237 if (area) {
2238 for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
2239 for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2;
2240 level++) {
2241 struct isis_spftree *spftree;
2242 struct isis_vertex *vertex_psid;
2243
2244 if (!(area->is_type & level))
2245 continue;
2246 spftree = area->spftree[tree][level - 1];
2247 if (!spftree)
2248 continue;
2249
2250 vertex_psid = isis_spf_prefix_sid_lookup(
2251 spftree, &psid);
2252 if (vertex_psid
2253 && !prefix_same(&vertex_psid->N.ip.p.dest,
2254 &prefix)) {
2255 snprintfrr(
2256 args->errmsg, args->errmsg_len,
2257 "Prefix-SID collision detected, SID %s %u is already in use by prefix %pFX (L%u)",
2258 CHECK_FLAG(
2259 psid.flags,
2260 ISIS_PREFIX_SID_VALUE)
2261 ? "label"
2262 : "index",
2263 psid.value,
2264 &vertex_psid->N.ip.p.dest,
2265 level);
2266 return NB_ERR_VALIDATION;
2267 }
2268 }
2269 }
2270 }
2271
2272 return NB_OK;
2273 }
2274
2275 void isis_instance_segment_routing_prefix_sid_map_prefix_sid_apply_finish(
2276 struct nb_cb_apply_finish_args *args)
2277 {
2278 struct sr_prefix_cfg *pcfg;
2279 struct isis_area *area;
2280
2281 pcfg = nb_running_get_entry(args->dnode, NULL, true);
2282 area = pcfg->area;
2283 lsp_regenerate_schedule(area, area->is_type, 0);
2284 }
2285
2286 /*
2287 * XPath:
2288 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/sid-value-type
2289 */
2290 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_type_modify(
2291 struct nb_cb_modify_args *args)
2292 {
2293 struct sr_prefix_cfg *pcfg;
2294
2295 if (args->event != NB_EV_APPLY)
2296 return NB_OK;
2297
2298 pcfg = nb_running_get_entry(args->dnode, NULL, true);
2299 pcfg->sid_type = yang_dnode_get_enum(args->dnode, NULL);
2300
2301 return NB_OK;
2302 }
2303
2304 /*
2305 * XPath:
2306 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/sid-value
2307 */
2308 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify(
2309 struct nb_cb_modify_args *args)
2310 {
2311 struct sr_prefix_cfg *pcfg;
2312
2313 if (args->event != NB_EV_APPLY)
2314 return NB_OK;
2315
2316 pcfg = nb_running_get_entry(args->dnode, NULL, true);
2317 pcfg->sid = yang_dnode_get_uint32(args->dnode, NULL);
2318
2319 return NB_OK;
2320 }
2321
2322 /*
2323 * XPath:
2324 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/last-hop-behavior
2325 */
2326 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
2327 struct nb_cb_modify_args *args)
2328 {
2329 struct sr_prefix_cfg *pcfg;
2330
2331 if (args->event != NB_EV_APPLY)
2332 return NB_OK;
2333
2334 pcfg = nb_running_get_entry(args->dnode, NULL, true);
2335 pcfg->last_hop_behavior = yang_dnode_get_enum(args->dnode, NULL);
2336
2337 return NB_OK;
2338 }
2339
2340 /*
2341 * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear
2342 */
2343 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
2344 struct nb_cb_modify_args *args)
2345 {
2346 struct sr_prefix_cfg *pcfg;
2347
2348 if (args->event != NB_EV_APPLY)
2349 return NB_OK;
2350
2351 pcfg = nb_running_get_entry(args->dnode, NULL, true);
2352 pcfg->n_flag_clear = yang_dnode_get_bool(args->dnode, NULL);
2353
2354 return NB_OK;
2355 }
2356
2357 /*
2358 * XPath: /frr-isisd:isis/instance/mpls/ldp-sync
2359 */
2360 int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
2361 {
2362 struct isis_area *area;
2363
2364 switch (args->event) {
2365 case NB_EV_VALIDATE:
2366 area = nb_running_get_entry(args->dnode, NULL, false);
2367 if (area == NULL || area->isis == NULL)
2368 return NB_ERR_VALIDATION;
2369
2370 if (area->isis->vrf_id != VRF_DEFAULT) {
2371 snprintf(args->errmsg, args->errmsg_len,
2372 "LDP-Sync only runs on Default VRF");
2373 return NB_ERR_VALIDATION;
2374 }
2375 break;
2376 case NB_EV_PREPARE:
2377 case NB_EV_ABORT:
2378 break;
2379 case NB_EV_APPLY:
2380 area = nb_running_get_entry(args->dnode, NULL, true);
2381 isis_area_ldp_sync_enable(area);
2382 break;
2383 }
2384 return NB_OK;
2385 }
2386
2387 int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args)
2388 {
2389 struct isis_area *area;
2390
2391 if (args->event != NB_EV_APPLY)
2392 return NB_OK;
2393
2394 area = nb_running_get_entry(args->dnode, NULL, true);
2395 isis_area_ldp_sync_disable(area);
2396
2397 return NB_OK;
2398 }
2399
2400 /*
2401 * XPath: /frr-isisd:isis/instance/mpls/ldp-sync/holddown
2402 */
2403 int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
2404 {
2405 struct isis_area *area;
2406 uint16_t holddown;
2407
2408 switch (args->event) {
2409 case NB_EV_VALIDATE:
2410 area = nb_running_get_entry(args->dnode, NULL, false);
2411 if (area == NULL || area->isis == NULL)
2412 return NB_ERR_VALIDATION;
2413
2414 if (area->isis->vrf_id != VRF_DEFAULT) {
2415 snprintf(args->errmsg, args->errmsg_len,
2416 "LDP-Sync only runs on Default VRF");
2417 return NB_ERR_VALIDATION;
2418 }
2419 break;
2420 case NB_EV_PREPARE:
2421 case NB_EV_ABORT:
2422 break;
2423 case NB_EV_APPLY:
2424 area = nb_running_get_entry(args->dnode, NULL, true);
2425 holddown = yang_dnode_get_uint16(args->dnode, NULL);
2426 isis_area_ldp_sync_set_holddown(area, holddown);
2427 break;
2428 }
2429 return NB_OK;
2430 }
2431
2432 /*
2433 * XPath: /frr-interface:lib/interface/frr-isisd:isis
2434 */
2435 int lib_interface_isis_create(struct nb_cb_create_args *args)
2436 {
2437 struct isis_area *area = NULL;
2438 struct interface *ifp;
2439 struct isis_circuit *circuit = NULL;
2440 const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
2441 uint32_t min_mtu, actual_mtu;
2442
2443 switch (args->event) {
2444 case NB_EV_PREPARE:
2445 case NB_EV_ABORT:
2446 break;
2447 case NB_EV_VALIDATE:
2448 /* check if interface mtu is sufficient. If the area has not
2449 * been created yet, assume default MTU for the area
2450 */
2451 ifp = nb_running_get_entry(args->dnode, NULL, false);
2452 /* zebra might not know yet about the MTU - nothing we can do */
2453 if (!ifp || ifp->mtu == 0)
2454 break;
2455 actual_mtu =
2456 if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
2457
2458 area = isis_area_lookup(area_tag, ifp->vrf_id);
2459 if (area)
2460 min_mtu = area->lsp_mtu;
2461 else
2462 #ifndef FABRICD
2463 min_mtu = yang_get_default_uint16(
2464 "/frr-isisd:isis/instance/lsp/mtu");
2465 #else
2466 min_mtu = DEFAULT_LSP_MTU;
2467 #endif /* ifndef FABRICD */
2468 if (actual_mtu < min_mtu) {
2469 snprintf(args->errmsg, args->errmsg_len,
2470 "Interface %s has MTU %u, minimum MTU for the area is %u",
2471 ifp->name, actual_mtu, min_mtu);
2472 return NB_ERR_VALIDATION;
2473 }
2474 break;
2475 case NB_EV_APPLY:
2476 ifp = nb_running_get_entry(args->dnode, NULL, true);
2477 circuit = isis_circuit_new(ifp, area_tag);
2478 nb_running_set_entry(args->dnode, circuit);
2479 break;
2480 }
2481
2482 return NB_OK;
2483 }
2484
2485 int lib_interface_isis_destroy(struct nb_cb_destroy_args *args)
2486 {
2487 struct isis_circuit *circuit;
2488
2489 if (args->event != NB_EV_APPLY)
2490 return NB_OK;
2491
2492 circuit = nb_running_unset_entry(args->dnode);
2493
2494 isis_circuit_del(circuit);
2495
2496 return NB_OK;
2497 }
2498
2499 /*
2500 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
2501 */
2502 int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
2503 {
2504 struct isis_circuit *circuit;
2505 struct interface *ifp;
2506 struct vrf *vrf;
2507 const char *area_tag, *ifname, *vrfname;
2508
2509 if (args->event == NB_EV_VALIDATE) {
2510 /* libyang doesn't like relative paths across module boundaries
2511 */
2512 ifname = yang_dnode_get_string(
2513 lyd_parent(lyd_parent(args->dnode)), "./name");
2514 vrfname = yang_dnode_get_string(
2515 lyd_parent(lyd_parent(args->dnode)), "./vrf");
2516 vrf = vrf_lookup_by_name(vrfname);
2517 assert(vrf);
2518 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
2519
2520 if (!ifp)
2521 return NB_OK;
2522
2523 circuit = circuit_scan_by_ifp(ifp);
2524 area_tag = yang_dnode_get_string(args->dnode, NULL);
2525 if (circuit && circuit->area && circuit->area->area_tag
2526 && strcmp(circuit->area->area_tag, area_tag)) {
2527 snprintf(args->errmsg, args->errmsg_len,
2528 "ISIS circuit is already defined on %s",
2529 circuit->area->area_tag);
2530 return NB_ERR_VALIDATION;
2531 }
2532 }
2533
2534 return NB_OK;
2535 }
2536
2537 /*
2538 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
2539 */
2540 int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
2541 {
2542 int circ_type = yang_dnode_get_enum(args->dnode, NULL);
2543 struct isis_circuit *circuit;
2544 struct interface *ifp;
2545 struct vrf *vrf;
2546 const char *ifname, *vrfname;
2547
2548 switch (args->event) {
2549 case NB_EV_VALIDATE:
2550 /* libyang doesn't like relative paths across module boundaries
2551 */
2552 ifname = yang_dnode_get_string(
2553 lyd_parent(lyd_parent(args->dnode)), "./name");
2554 vrfname = yang_dnode_get_string(
2555 lyd_parent(lyd_parent(args->dnode)), "./vrf");
2556 vrf = vrf_lookup_by_name(vrfname);
2557 assert(vrf);
2558 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
2559 if (!ifp)
2560 break;
2561
2562 circuit = circuit_scan_by_ifp(ifp);
2563 if (circuit && circuit->state == C_STATE_UP
2564 && circuit->area->is_type != IS_LEVEL_1_AND_2
2565 && circuit->area->is_type != circ_type) {
2566 snprintf(args->errmsg, args->errmsg_len,
2567 "Invalid circuit level for area %s",
2568 circuit->area->area_tag);
2569 return NB_ERR_VALIDATION;
2570 }
2571 break;
2572 case NB_EV_PREPARE:
2573 case NB_EV_ABORT:
2574 break;
2575 case NB_EV_APPLY:
2576 circuit = nb_running_get_entry(args->dnode, NULL, true);
2577 isis_circuit_is_type_set(circuit, circ_type);
2578 break;
2579 }
2580
2581 return NB_OK;
2582 }
2583
2584 /*
2585 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
2586 */
2587 int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args)
2588 {
2589 bool ipv4, ipv6;
2590 struct isis_circuit *circuit;
2591
2592 if (args->event != NB_EV_APPLY)
2593 return NB_OK;
2594
2595 circuit = nb_running_get_entry(args->dnode, NULL, true);
2596 ipv4 = yang_dnode_get_bool(args->dnode, NULL);
2597 ipv6 = yang_dnode_get_bool(args->dnode, "../ipv6-routing");
2598 isis_circuit_af_set(circuit, ipv4, ipv6);
2599
2600 return NB_OK;
2601 }
2602
2603 /*
2604 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
2605 */
2606 int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args)
2607 {
2608 bool ipv4, ipv6;
2609 struct isis_circuit *circuit;
2610
2611 if (args->event != NB_EV_APPLY)
2612 return NB_OK;
2613
2614 circuit = nb_running_get_entry(args->dnode, NULL, true);
2615 ipv4 = yang_dnode_get_bool(args->dnode, "../ipv4-routing");
2616 ipv6 = yang_dnode_get_bool(args->dnode, NULL);
2617 isis_circuit_af_set(circuit, ipv4, ipv6);
2618
2619 return NB_OK;
2620 }
2621
2622 /*
2623 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
2624 */
2625 void lib_interface_isis_bfd_monitoring_apply_finish(
2626 struct nb_cb_apply_finish_args *args)
2627 {
2628 struct isis_circuit *circuit;
2629
2630 circuit = nb_running_get_entry(args->dnode, NULL, true);
2631 isis_bfd_circuit_cmd(circuit);
2632 }
2633
2634 /*
2635 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/enabled
2636 */
2637 int lib_interface_isis_bfd_monitoring_enabled_modify(
2638 struct nb_cb_modify_args *args)
2639 {
2640 struct isis_circuit *circuit;
2641
2642 if (args->event != NB_EV_APPLY)
2643 return NB_OK;
2644
2645 circuit = nb_running_get_entry(args->dnode, NULL, true);
2646 circuit->bfd_config.enabled = yang_dnode_get_bool(args->dnode, NULL);
2647
2648 return NB_OK;
2649 }
2650
2651 /*
2652 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile
2653 */
2654 int lib_interface_isis_bfd_monitoring_profile_modify(
2655 struct nb_cb_modify_args *args)
2656 {
2657 struct isis_circuit *circuit;
2658
2659 if (args->event != NB_EV_APPLY)
2660 return NB_OK;
2661
2662 circuit = nb_running_get_entry(args->dnode, NULL, true);
2663 XFREE(MTYPE_TMP, circuit->bfd_config.profile);
2664 circuit->bfd_config.profile =
2665 XSTRDUP(MTYPE_TMP, yang_dnode_get_string(args->dnode, NULL));
2666
2667 return NB_OK;
2668 }
2669
2670 int lib_interface_isis_bfd_monitoring_profile_destroy(
2671 struct nb_cb_destroy_args *args)
2672 {
2673 struct isis_circuit *circuit;
2674
2675 if (args->event != NB_EV_APPLY)
2676 return NB_OK;
2677
2678 circuit = nb_running_get_entry(args->dnode, NULL, true);
2679 XFREE(MTYPE_TMP, circuit->bfd_config.profile);
2680
2681 return NB_OK;
2682 }
2683
2684 /*
2685 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
2686 */
2687 int lib_interface_isis_csnp_interval_level_1_modify(
2688 struct nb_cb_modify_args *args)
2689 {
2690 struct isis_circuit *circuit;
2691
2692 if (args->event != NB_EV_APPLY)
2693 return NB_OK;
2694
2695 circuit = nb_running_get_entry(args->dnode, NULL, true);
2696 circuit->csnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
2697
2698 return NB_OK;
2699 }
2700
2701 /*
2702 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
2703 */
2704 int lib_interface_isis_csnp_interval_level_2_modify(
2705 struct nb_cb_modify_args *args)
2706 {
2707 struct isis_circuit *circuit;
2708
2709 if (args->event != NB_EV_APPLY)
2710 return NB_OK;
2711
2712 circuit = nb_running_get_entry(args->dnode, NULL, true);
2713 circuit->csnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
2714
2715 return NB_OK;
2716 }
2717
2718 /*
2719 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
2720 */
2721 int lib_interface_isis_psnp_interval_level_1_modify(
2722 struct nb_cb_modify_args *args)
2723 {
2724 struct isis_circuit *circuit;
2725
2726 if (args->event != NB_EV_APPLY)
2727 return NB_OK;
2728
2729 circuit = nb_running_get_entry(args->dnode, NULL, true);
2730 circuit->psnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
2731
2732 return NB_OK;
2733 }
2734
2735 /*
2736 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
2737 */
2738 int lib_interface_isis_psnp_interval_level_2_modify(
2739 struct nb_cb_modify_args *args)
2740 {
2741 struct isis_circuit *circuit;
2742
2743 if (args->event != NB_EV_APPLY)
2744 return NB_OK;
2745
2746 circuit = nb_running_get_entry(args->dnode, NULL, true);
2747 circuit->psnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
2748
2749 return NB_OK;
2750 }
2751
2752 /*
2753 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
2754 */
2755 int lib_interface_isis_hello_padding_modify(struct nb_cb_modify_args *args)
2756 {
2757 struct isis_circuit *circuit;
2758
2759 if (args->event != NB_EV_APPLY)
2760 return NB_OK;
2761
2762 circuit = nb_running_get_entry(args->dnode, NULL, true);
2763 circuit->pad_hellos = yang_dnode_get_bool(args->dnode, NULL);
2764
2765 return NB_OK;
2766 }
2767
2768 /*
2769 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
2770 */
2771 int lib_interface_isis_hello_interval_level_1_modify(
2772 struct nb_cb_modify_args *args)
2773 {
2774 struct isis_circuit *circuit;
2775 uint32_t interval;
2776
2777 if (args->event != NB_EV_APPLY)
2778 return NB_OK;
2779
2780 circuit = nb_running_get_entry(args->dnode, NULL, true);
2781 interval = yang_dnode_get_uint32(args->dnode, NULL);
2782 circuit->hello_interval[0] = interval;
2783
2784 return NB_OK;
2785 }
2786
2787 /*
2788 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
2789 */
2790 int lib_interface_isis_hello_interval_level_2_modify(
2791 struct nb_cb_modify_args *args)
2792 {
2793 struct isis_circuit *circuit;
2794 uint32_t interval;
2795
2796 if (args->event != NB_EV_APPLY)
2797 return NB_OK;
2798
2799 circuit = nb_running_get_entry(args->dnode, NULL, true);
2800 interval = yang_dnode_get_uint32(args->dnode, NULL);
2801 circuit->hello_interval[1] = interval;
2802
2803 return NB_OK;
2804 }
2805
2806 /*
2807 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
2808 */
2809 int lib_interface_isis_hello_multiplier_level_1_modify(
2810 struct nb_cb_modify_args *args)
2811 {
2812 struct isis_circuit *circuit;
2813 uint16_t multi;
2814
2815 if (args->event != NB_EV_APPLY)
2816 return NB_OK;
2817
2818 circuit = nb_running_get_entry(args->dnode, NULL, true);
2819 multi = yang_dnode_get_uint16(args->dnode, NULL);
2820 circuit->hello_multiplier[0] = multi;
2821
2822 return NB_OK;
2823 }
2824
2825 /*
2826 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
2827 */
2828 int lib_interface_isis_hello_multiplier_level_2_modify(
2829 struct nb_cb_modify_args *args)
2830 {
2831 struct isis_circuit *circuit;
2832 uint16_t multi;
2833
2834 if (args->event != NB_EV_APPLY)
2835 return NB_OK;
2836
2837 circuit = nb_running_get_entry(args->dnode, NULL, true);
2838 multi = yang_dnode_get_uint16(args->dnode, NULL);
2839 circuit->hello_multiplier[1] = multi;
2840
2841 return NB_OK;
2842 }
2843
2844 /*
2845 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
2846 */
2847 int lib_interface_isis_metric_level_1_modify(struct nb_cb_modify_args *args)
2848 {
2849 struct isis_circuit *circuit;
2850 unsigned int met;
2851
2852 if (args->event != NB_EV_APPLY)
2853 return NB_OK;
2854
2855 circuit = nb_running_get_entry(args->dnode, NULL, true);
2856 met = yang_dnode_get_uint32(args->dnode, NULL);
2857 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
2858
2859 return NB_OK;
2860 }
2861
2862 /*
2863 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
2864 */
2865 int lib_interface_isis_metric_level_2_modify(struct nb_cb_modify_args *args)
2866 {
2867 struct isis_circuit *circuit;
2868 unsigned int met;
2869
2870 if (args->event != NB_EV_APPLY)
2871 return NB_OK;
2872
2873 circuit = nb_running_get_entry(args->dnode, NULL, true);
2874 met = yang_dnode_get_uint32(args->dnode, NULL);
2875 isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
2876
2877 return NB_OK;
2878 }
2879
2880 /*
2881 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
2882 */
2883 int lib_interface_isis_priority_level_1_modify(struct nb_cb_modify_args *args)
2884 {
2885 struct isis_circuit *circuit;
2886
2887 if (args->event != NB_EV_APPLY)
2888 return NB_OK;
2889
2890 circuit = nb_running_get_entry(args->dnode, NULL, true);
2891 circuit->priority[0] = yang_dnode_get_uint8(args->dnode, NULL);
2892
2893 return NB_OK;
2894 }
2895
2896 /*
2897 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
2898 */
2899 int lib_interface_isis_priority_level_2_modify(struct nb_cb_modify_args *args)
2900 {
2901 struct isis_circuit *circuit;
2902
2903 if (args->event != NB_EV_APPLY)
2904 return NB_OK;
2905
2906 circuit = nb_running_get_entry(args->dnode, NULL, true);
2907 circuit->priority[1] = yang_dnode_get_uint8(args->dnode, NULL);
2908
2909 return NB_OK;
2910 }
2911
2912 /*
2913 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
2914 */
2915 int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args)
2916 {
2917 struct isis_circuit *circuit;
2918 int net_type = yang_dnode_get_enum(args->dnode, NULL);
2919
2920 switch (args->event) {
2921 case NB_EV_VALIDATE:
2922 circuit = nb_running_get_entry(args->dnode, NULL, false);
2923 if (!circuit)
2924 break;
2925 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
2926 snprintf(
2927 args->errmsg, args->errmsg_len,
2928 "Cannot change network type on loopback interface");
2929 return NB_ERR_VALIDATION;
2930 }
2931 if (net_type == CIRCUIT_T_BROADCAST
2932 && circuit->state == C_STATE_UP
2933 && !if_is_broadcast(circuit->interface)) {
2934 snprintf(
2935 args->errmsg, args->errmsg_len,
2936 "Cannot configure non-broadcast interface for broadcast operation");
2937 return NB_ERR_VALIDATION;
2938 }
2939 break;
2940 case NB_EV_PREPARE:
2941 case NB_EV_ABORT:
2942 break;
2943 case NB_EV_APPLY:
2944 circuit = nb_running_get_entry(args->dnode, NULL, true);
2945 isis_circuit_circ_type_set(circuit, net_type);
2946 break;
2947 }
2948
2949 return NB_OK;
2950 }
2951
2952 /*
2953 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2954 */
2955 int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
2956 {
2957 struct isis_circuit *circuit;
2958 struct interface *ifp;
2959 bool passive = yang_dnode_get_bool(args->dnode, NULL);
2960
2961 /* validation only applies if we are setting passive to false */
2962 if (!passive && args->event == NB_EV_VALIDATE) {
2963 circuit = nb_running_get_entry(args->dnode, NULL, false);
2964 if (!circuit)
2965 return NB_OK;
2966 ifp = circuit->interface;
2967 if (!ifp)
2968 return NB_OK;
2969 if (if_is_loopback(ifp)) {
2970 snprintf(args->errmsg, args->errmsg_len,
2971 "Loopback is always passive");
2972 return NB_ERR_VALIDATION;
2973 }
2974 }
2975
2976 if (args->event != NB_EV_APPLY)
2977 return NB_OK;
2978
2979 circuit = nb_running_get_entry(args->dnode, NULL, true);
2980 isis_circuit_passive_set(circuit, passive);
2981
2982 return NB_OK;
2983 }
2984
2985 /*
2986 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2987 */
2988 int lib_interface_isis_password_create(struct nb_cb_create_args *args)
2989 {
2990 return NB_OK;
2991 }
2992
2993 int lib_interface_isis_password_destroy(struct nb_cb_destroy_args *args)
2994 {
2995 struct isis_circuit *circuit;
2996
2997 if (args->event != NB_EV_APPLY)
2998 return NB_OK;
2999
3000 circuit = nb_running_get_entry(args->dnode, NULL, true);
3001 isis_circuit_passwd_unset(circuit);
3002
3003 return NB_OK;
3004 }
3005
3006 /*
3007 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
3008 */
3009 int lib_interface_isis_password_password_modify(struct nb_cb_modify_args *args)
3010 {
3011 struct isis_circuit *circuit;
3012 const char *password;
3013
3014 if (args->event != NB_EV_APPLY)
3015 return NB_OK;
3016
3017 password = yang_dnode_get_string(args->dnode, NULL);
3018 circuit = nb_running_get_entry(args->dnode, NULL, true);
3019
3020 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
3021
3022 return NB_OK;
3023 }
3024
3025 /*
3026 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
3027 */
3028 int lib_interface_isis_password_password_type_modify(
3029 struct nb_cb_modify_args *args)
3030 {
3031 struct isis_circuit *circuit;
3032 uint8_t pass_type;
3033
3034 if (args->event != NB_EV_APPLY)
3035 return NB_OK;
3036
3037 pass_type = yang_dnode_get_enum(args->dnode, NULL);
3038 circuit = nb_running_get_entry(args->dnode, NULL, true);
3039 circuit->passwd.type = pass_type;
3040
3041 return NB_OK;
3042 }
3043
3044 /*
3045 * XPath:
3046 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
3047 */
3048 int lib_interface_isis_disable_three_way_handshake_modify(
3049 struct nb_cb_modify_args *args)
3050 {
3051 struct isis_circuit *circuit;
3052
3053 if (args->event != NB_EV_APPLY)
3054 return NB_OK;
3055
3056 circuit = nb_running_get_entry(args->dnode, NULL, true);
3057 circuit->disable_threeway_adj = yang_dnode_get_bool(args->dnode, NULL);
3058
3059 return NB_OK;
3060 }
3061
3062 /*
3063 * XPath:
3064 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
3065 */
3066 static int lib_interface_isis_multi_topology_common(
3067 enum nb_event event, const struct lyd_node *dnode, char *errmsg,
3068 size_t errmsg_len, uint16_t mtid)
3069 {
3070 struct isis_circuit *circuit;
3071 bool value;
3072
3073 switch (event) {
3074 case NB_EV_VALIDATE:
3075 circuit = nb_running_get_entry(dnode, NULL, false);
3076 if (circuit && circuit->area && circuit->area->oldmetric) {
3077 snprintf(
3078 errmsg, errmsg_len,
3079 "Multi topology IS-IS can only be used with wide metrics");
3080 return NB_ERR_VALIDATION;
3081 }
3082 break;
3083 case NB_EV_PREPARE:
3084 case NB_EV_ABORT:
3085 break;
3086 case NB_EV_APPLY:
3087 circuit = nb_running_get_entry(dnode, NULL, true);
3088 value = yang_dnode_get_bool(dnode, NULL);
3089 isis_circuit_mt_enabled_set(circuit, mtid, value);
3090 break;
3091 }
3092
3093 return NB_OK;
3094 }
3095
3096 int lib_interface_isis_multi_topology_ipv4_unicast_modify(
3097 struct nb_cb_modify_args *args)
3098 {
3099 return lib_interface_isis_multi_topology_common(
3100 args->event, args->dnode, args->errmsg, args->errmsg_len,
3101 ISIS_MT_IPV4_UNICAST);
3102 }
3103
3104 /*
3105 * XPath:
3106 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
3107 */
3108 int lib_interface_isis_multi_topology_ipv4_multicast_modify(
3109 struct nb_cb_modify_args *args)
3110 {
3111 return lib_interface_isis_multi_topology_common(
3112 args->event, args->dnode, args->errmsg, args->errmsg_len,
3113 ISIS_MT_IPV4_MULTICAST);
3114 }
3115
3116 /*
3117 * XPath:
3118 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
3119 */
3120 int lib_interface_isis_multi_topology_ipv4_management_modify(
3121 struct nb_cb_modify_args *args)
3122 {
3123 return lib_interface_isis_multi_topology_common(
3124 args->event, args->dnode, args->errmsg, args->errmsg_len,
3125 ISIS_MT_IPV4_MGMT);
3126 }
3127
3128 /*
3129 * XPath:
3130 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
3131 */
3132 int lib_interface_isis_multi_topology_ipv6_unicast_modify(
3133 struct nb_cb_modify_args *args)
3134 {
3135 return lib_interface_isis_multi_topology_common(
3136 args->event, args->dnode, args->errmsg, args->errmsg_len,
3137 ISIS_MT_IPV6_UNICAST);
3138 }
3139
3140 /*
3141 * XPath:
3142 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
3143 */
3144 int lib_interface_isis_multi_topology_ipv6_multicast_modify(
3145 struct nb_cb_modify_args *args)
3146 {
3147 return lib_interface_isis_multi_topology_common(
3148 args->event, args->dnode, args->errmsg, args->errmsg_len,
3149 ISIS_MT_IPV6_MULTICAST);
3150 }
3151
3152 /*
3153 * XPath:
3154 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
3155 */
3156 int lib_interface_isis_multi_topology_ipv6_management_modify(
3157 struct nb_cb_modify_args *args)
3158 {
3159 return lib_interface_isis_multi_topology_common(
3160 args->event, args->dnode, args->errmsg, args->errmsg_len,
3161 ISIS_MT_IPV6_MGMT);
3162 }
3163
3164 /*
3165 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
3166 */
3167 int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
3168 struct nb_cb_modify_args *args)
3169 {
3170 return lib_interface_isis_multi_topology_common(
3171 args->event, args->dnode, args->errmsg, args->errmsg_len,
3172 ISIS_MT_IPV6_DSTSRC);
3173 }
3174
3175 /*
3176 * XPath: /frr-interface:lib/interface/frr-isisd:isis/mpls/ldp-sync
3177 */
3178 int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
3179 {
3180 struct isis_circuit *circuit;
3181 struct ldp_sync_info *ldp_sync_info;
3182 bool ldp_sync_enable;
3183 struct interface *ifp;
3184
3185 switch (args->event) {
3186 case NB_EV_VALIDATE:
3187 ifp = nb_running_get_entry(
3188 lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
3189 false);
3190 if (ifp == NULL)
3191 return NB_ERR_VALIDATION;
3192 if (if_is_loopback(ifp)) {
3193 snprintf(args->errmsg, args->errmsg_len,
3194 "LDP-Sync does not run on loopback interface");
3195 return NB_ERR_VALIDATION;
3196 }
3197
3198 circuit = nb_running_get_entry(args->dnode, NULL, false);
3199 if (circuit == NULL || circuit->area == NULL)
3200 break;
3201
3202 if (circuit->isis->vrf_id != VRF_DEFAULT) {
3203 snprintf(args->errmsg, args->errmsg_len,
3204 "LDP-Sync only runs on Default VRF");
3205 return NB_ERR_VALIDATION;
3206 }
3207 break;
3208 case NB_EV_PREPARE:
3209 case NB_EV_ABORT:
3210 break;
3211 case NB_EV_APPLY:
3212 circuit = nb_running_get_entry(args->dnode, NULL, true);
3213 ldp_sync_enable = yang_dnode_get_bool(args->dnode, NULL);
3214
3215 ldp_sync_info = circuit->ldp_sync_info;
3216
3217 SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
3218 ldp_sync_info->enabled = ldp_sync_enable;
3219
3220 if (circuit->area) {
3221 if (ldp_sync_enable)
3222 isis_if_ldp_sync_enable(circuit);
3223 else
3224 isis_if_ldp_sync_disable(circuit);
3225 }
3226 break;
3227 }
3228 return NB_OK;
3229 }
3230
3231 /*
3232 * XPath: /frr-interface:lib/interface/frr-isisd:isis/mpls/holddown
3233 */
3234 int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
3235 {
3236 struct isis_circuit *circuit;
3237 struct ldp_sync_info *ldp_sync_info;
3238 uint16_t holddown;
3239 struct interface *ifp;
3240
3241 switch (args->event) {
3242 case NB_EV_VALIDATE:
3243
3244 ifp = nb_running_get_entry(
3245 lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
3246 false);
3247 if (ifp == NULL)
3248 return NB_ERR_VALIDATION;
3249 if (if_is_loopback(ifp)) {
3250 snprintf(args->errmsg, args->errmsg_len,
3251 "LDP-Sync does not run on loopback interface");
3252 return NB_ERR_VALIDATION;
3253 }
3254
3255 circuit = nb_running_get_entry(args->dnode, NULL, false);
3256 if (circuit == NULL || circuit->area == NULL)
3257 break;
3258
3259 if (circuit->isis->vrf_id != VRF_DEFAULT) {
3260 snprintf(args->errmsg, args->errmsg_len,
3261 "LDP-Sync only runs on Default VRF");
3262 return NB_ERR_VALIDATION;
3263 }
3264 break;
3265 case NB_EV_PREPARE:
3266 case NB_EV_ABORT:
3267 break;
3268 case NB_EV_APPLY:
3269 circuit = nb_running_get_entry(args->dnode, NULL, true);
3270 holddown = yang_dnode_get_uint16(args->dnode, NULL);
3271
3272 ldp_sync_info = circuit->ldp_sync_info;
3273
3274 SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
3275 ldp_sync_info->holddown = holddown;
3276 break;
3277 }
3278 return NB_OK;
3279 }
3280
3281 int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
3282 {
3283 struct isis_circuit *circuit;
3284 struct ldp_sync_info *ldp_sync_info;
3285 struct interface *ifp;
3286
3287 switch (args->event) {
3288 case NB_EV_VALIDATE:
3289 ifp = nb_running_get_entry(
3290 lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
3291 false);
3292 if (ifp == NULL)
3293 return NB_ERR_VALIDATION;
3294 if (if_is_loopback(ifp)) {
3295 snprintf(args->errmsg, args->errmsg_len,
3296 "LDP-Sync does not run on loopback interface");
3297 return NB_ERR_VALIDATION;
3298 }
3299
3300 circuit = nb_running_get_entry(args->dnode, NULL, false);
3301 if (circuit == NULL || circuit->area == NULL)
3302 break;
3303
3304 if (circuit->isis->vrf_id != VRF_DEFAULT) {
3305 snprintf(args->errmsg, args->errmsg_len,
3306 "LDP-Sync only runs on Default VRF");
3307 return NB_ERR_VALIDATION;
3308 }
3309 break;
3310 case NB_EV_PREPARE:
3311 case NB_EV_ABORT:
3312 break;
3313 case NB_EV_APPLY:
3314 circuit = nb_running_get_entry(args->dnode, NULL, true);
3315 ldp_sync_info = circuit->ldp_sync_info;
3316
3317 UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
3318
3319 if (circuit->area)
3320 isis_if_set_ldp_sync_holddown(circuit);
3321 break;
3322 }
3323
3324 return NB_OK;
3325 }
3326
3327 /*
3328 * XPath:
3329 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/lfa/enable
3330 */
3331 int lib_interface_isis_fast_reroute_level_1_lfa_enable_modify(
3332 struct nb_cb_modify_args *args)
3333 {
3334 struct isis_area *area;
3335 struct isis_circuit *circuit;
3336
3337 if (args->event != NB_EV_APPLY)
3338 return NB_OK;
3339
3340 circuit = nb_running_get_entry(args->dnode, NULL, true);
3341 circuit->lfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
3342
3343 area = circuit->area;
3344 if (area) {
3345 if (circuit->lfa_protection[0])
3346 area->lfa_protected_links[0]++;
3347 else {
3348 assert(area->lfa_protected_links[0] > 0);
3349 area->lfa_protected_links[0]--;
3350 }
3351
3352 lsp_regenerate_schedule(area, area->is_type, 0);
3353 }
3354
3355 return NB_OK;
3356 }
3357
3358 /*
3359 * XPath:
3360 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface
3361 */
3362 int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_create(
3363 struct nb_cb_create_args *args)
3364 {
3365 struct isis_area *area;
3366 struct isis_circuit *circuit;
3367 const char *exclude_ifname;
3368
3369 if (args->event != NB_EV_APPLY)
3370 return NB_OK;
3371
3372 circuit = nb_running_get_entry(args->dnode, NULL, true);
3373 exclude_ifname = yang_dnode_get_string(args->dnode, NULL);
3374
3375 isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL1, exclude_ifname);
3376 area = circuit->area;
3377 if (area)
3378 lsp_regenerate_schedule(area, area->is_type, 0);
3379
3380 return NB_OK;
3381 }
3382
3383 int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_destroy(
3384 struct nb_cb_destroy_args *args)
3385 {
3386 struct isis_area *area;
3387 struct isis_circuit *circuit;
3388 const char *exclude_ifname;
3389
3390 if (args->event != NB_EV_APPLY)
3391 return NB_OK;
3392
3393 circuit = nb_running_get_entry(args->dnode, NULL, true);
3394 exclude_ifname = yang_dnode_get_string(args->dnode, NULL);
3395
3396 isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL1, exclude_ifname);
3397 area = circuit->area;
3398 if (area)
3399 lsp_regenerate_schedule(area, area->is_type, 0);
3400
3401 return NB_OK;
3402 }
3403
3404 /*
3405 * XPath:
3406 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable
3407 */
3408 int lib_interface_isis_fast_reroute_level_1_remote_lfa_enable_modify(
3409 struct nb_cb_modify_args *args)
3410 {
3411 struct isis_area *area;
3412 struct isis_circuit *circuit;
3413
3414 if (args->event != NB_EV_APPLY)
3415 return NB_OK;
3416
3417 circuit = nb_running_get_entry(args->dnode, NULL, true);
3418 circuit->rlfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
3419
3420 area = circuit->area;
3421 if (area) {
3422 if (circuit->rlfa_protection[0])
3423 area->rlfa_protected_links[0]++;
3424 else {
3425 assert(area->rlfa_protected_links[0] > 0);
3426 area->rlfa_protected_links[0]--;
3427 }
3428
3429 lsp_regenerate_schedule(area, area->is_type, 0);
3430 }
3431
3432 return NB_OK;
3433 }
3434
3435 /*
3436 * XPath:
3437 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric
3438 */
3439 int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_modify(
3440 struct nb_cb_modify_args *args)
3441 {
3442 struct isis_area *area;
3443 struct isis_circuit *circuit;
3444
3445 if (args->event != NB_EV_APPLY)
3446 return NB_OK;
3447
3448 circuit = nb_running_get_entry(args->dnode, NULL, true);
3449 circuit->rlfa_max_metric[0] = yang_dnode_get_uint32(args->dnode, NULL);
3450
3451 area = circuit->area;
3452 if (area)
3453 lsp_regenerate_schedule(area, area->is_type, 0);
3454
3455 return NB_OK;
3456 }
3457
3458 int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_destroy(
3459 struct nb_cb_destroy_args *args)
3460 {
3461 struct isis_area *area;
3462 struct isis_circuit *circuit;
3463
3464 if (args->event != NB_EV_APPLY)
3465 return NB_OK;
3466
3467 circuit = nb_running_get_entry(args->dnode, NULL, true);
3468 circuit->rlfa_max_metric[0] = 0;
3469
3470 area = circuit->area;
3471 if (area)
3472 lsp_regenerate_schedule(area, area->is_type, 0);
3473
3474 return NB_OK;
3475 }
3476
3477 /*
3478 * XPath:
3479 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable
3480 */
3481 int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
3482 struct nb_cb_modify_args *args)
3483 {
3484 struct isis_area *area;
3485 struct isis_circuit *circuit;
3486
3487 if (args->event != NB_EV_APPLY)
3488 return NB_OK;
3489
3490 circuit = nb_running_get_entry(args->dnode, NULL, true);
3491 circuit->tilfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
3492
3493 area = circuit->area;
3494 if (area) {
3495 if (circuit->tilfa_protection[0])
3496 area->tilfa_protected_links[0]++;
3497 else {
3498 assert(area->tilfa_protected_links[0] > 0);
3499 area->tilfa_protected_links[0]--;
3500 }
3501
3502 lsp_regenerate_schedule(area, area->is_type, 0);
3503 }
3504
3505 return NB_OK;
3506 }
3507
3508 /*
3509 * XPath:
3510 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection
3511 */
3512 int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
3513 struct nb_cb_modify_args *args)
3514 {
3515 struct isis_area *area;
3516 struct isis_circuit *circuit;
3517
3518 if (args->event != NB_EV_APPLY)
3519 return NB_OK;
3520
3521 circuit = nb_running_get_entry(args->dnode, NULL, true);
3522 circuit->tilfa_node_protection[0] =
3523 yang_dnode_get_bool(args->dnode, NULL);
3524
3525 area = circuit->area;
3526 if (area)
3527 lsp_regenerate_schedule(area, area->is_type, 0);
3528
3529 return NB_OK;
3530 }
3531
3532 /*
3533 * XPath:
3534 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback
3535 */
3536 int lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify(
3537 struct nb_cb_modify_args *args)
3538 {
3539 struct isis_area *area;
3540 struct isis_circuit *circuit;
3541
3542 if (args->event != NB_EV_APPLY)
3543 return NB_OK;
3544
3545 circuit = nb_running_get_entry(args->dnode, NULL, true);
3546 circuit->tilfa_link_fallback[0] =
3547 yang_dnode_get_bool(args->dnode, NULL);
3548
3549 area = circuit->area;
3550 if (area)
3551 lsp_regenerate_schedule(area, area->is_type, 0);
3552
3553 return NB_OK;
3554 }
3555
3556 /*
3557 * XPath:
3558 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/lfa/enable
3559 */
3560 int lib_interface_isis_fast_reroute_level_2_lfa_enable_modify(
3561 struct nb_cb_modify_args *args)
3562 {
3563 struct isis_area *area;
3564 struct isis_circuit *circuit;
3565
3566 if (args->event != NB_EV_APPLY)
3567 return NB_OK;
3568
3569 circuit = nb_running_get_entry(args->dnode, NULL, true);
3570 circuit->lfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
3571
3572 area = circuit->area;
3573 if (area) {
3574 if (circuit->lfa_protection[1])
3575 area->lfa_protected_links[1]++;
3576 else {
3577 assert(area->lfa_protected_links[1] > 0);
3578 area->lfa_protected_links[1]--;
3579 }
3580
3581 lsp_regenerate_schedule(area, area->is_type, 0);
3582 }
3583
3584 return NB_OK;
3585 }
3586
3587 /*
3588 * XPath:
3589 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface
3590 */
3591 int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_create(
3592 struct nb_cb_create_args *args)
3593 {
3594 struct isis_area *area;
3595 struct isis_circuit *circuit;
3596 const char *exclude_ifname;
3597
3598 if (args->event != NB_EV_APPLY)
3599 return NB_OK;
3600
3601 circuit = nb_running_get_entry(args->dnode, NULL, true);
3602 exclude_ifname = yang_dnode_get_string(args->dnode, NULL);
3603
3604 isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL2, exclude_ifname);
3605 area = circuit->area;
3606 if (area)
3607 lsp_regenerate_schedule(area, area->is_type, 0);
3608
3609 return NB_OK;
3610 }
3611
3612 int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_destroy(
3613 struct nb_cb_destroy_args *args)
3614 {
3615 struct isis_area *area;
3616 struct isis_circuit *circuit;
3617 const char *exclude_ifname;
3618
3619 if (args->event != NB_EV_APPLY)
3620 return NB_OK;
3621
3622 circuit = nb_running_get_entry(args->dnode, NULL, true);
3623 exclude_ifname = yang_dnode_get_string(args->dnode, NULL);
3624
3625 isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL2, exclude_ifname);
3626 area = circuit->area;
3627 if (area)
3628 lsp_regenerate_schedule(area, area->is_type, 0);
3629
3630 return NB_OK;
3631 }
3632
3633 /*
3634 * XPath:
3635 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable
3636 */
3637 int lib_interface_isis_fast_reroute_level_2_remote_lfa_enable_modify(
3638 struct nb_cb_modify_args *args)
3639 {
3640 struct isis_area *area;
3641 struct isis_circuit *circuit;
3642
3643 if (args->event != NB_EV_APPLY)
3644 return NB_OK;
3645
3646 circuit = nb_running_get_entry(args->dnode, NULL, true);
3647 circuit->rlfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
3648
3649 area = circuit->area;
3650 if (area) {
3651 if (circuit->rlfa_protection[1])
3652 area->rlfa_protected_links[1]++;
3653 else {
3654 assert(area->rlfa_protected_links[1] > 0);
3655 area->rlfa_protected_links[1]--;
3656 }
3657
3658 lsp_regenerate_schedule(area, area->is_type, 0);
3659 }
3660
3661 return NB_OK;
3662 }
3663
3664 /*
3665 * XPath:
3666 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric
3667 */
3668 int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_modify(
3669 struct nb_cb_modify_args *args)
3670 {
3671 struct isis_area *area;
3672 struct isis_circuit *circuit;
3673
3674 if (args->event != NB_EV_APPLY)
3675 return NB_OK;
3676
3677 circuit = nb_running_get_entry(args->dnode, NULL, true);
3678 circuit->rlfa_max_metric[1] = yang_dnode_get_uint32(args->dnode, NULL);
3679
3680 area = circuit->area;
3681 if (area)
3682 lsp_regenerate_schedule(area, area->is_type, 0);
3683
3684 return NB_OK;
3685 }
3686
3687 int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_destroy(
3688 struct nb_cb_destroy_args *args)
3689 {
3690 struct isis_area *area;
3691 struct isis_circuit *circuit;
3692
3693 if (args->event != NB_EV_APPLY)
3694 return NB_OK;
3695
3696 circuit = nb_running_get_entry(args->dnode, NULL, true);
3697 circuit->rlfa_max_metric[1] = 0;
3698
3699 area = circuit->area;
3700 if (area)
3701 lsp_regenerate_schedule(area, area->is_type, 0);
3702
3703 return NB_OK;
3704 }
3705
3706 /*
3707 * XPath:
3708 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable
3709 */
3710 int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
3711 struct nb_cb_modify_args *args)
3712 {
3713 struct isis_area *area;
3714 struct isis_circuit *circuit;
3715
3716 if (args->event != NB_EV_APPLY)
3717 return NB_OK;
3718
3719 circuit = nb_running_get_entry(args->dnode, NULL, true);
3720 circuit->tilfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
3721
3722 area = circuit->area;
3723 if (area) {
3724 if (circuit->tilfa_protection[1])
3725 area->tilfa_protected_links[1]++;
3726 else {
3727 assert(area->tilfa_protected_links[1] > 0);
3728 area->tilfa_protected_links[1]--;
3729 }
3730
3731 lsp_regenerate_schedule(area, area->is_type, 0);
3732 }
3733
3734 return NB_OK;
3735 }
3736
3737 /*
3738 * XPath:
3739 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection
3740 */
3741 int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
3742 struct nb_cb_modify_args *args)
3743 {
3744 struct isis_area *area;
3745 struct isis_circuit *circuit;
3746
3747 if (args->event != NB_EV_APPLY)
3748 return NB_OK;
3749
3750 circuit = nb_running_get_entry(args->dnode, NULL, true);
3751 circuit->tilfa_node_protection[1] =
3752 yang_dnode_get_bool(args->dnode, NULL);
3753
3754 area = circuit->area;
3755 if (area)
3756 lsp_regenerate_schedule(area, area->is_type, 0);
3757
3758 return NB_OK;
3759 }
3760
3761 /*
3762 * XPath:
3763 * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback
3764 */
3765 int lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify(
3766 struct nb_cb_modify_args *args)
3767 {
3768 struct isis_area *area;
3769 struct isis_circuit *circuit;
3770
3771 if (args->event != NB_EV_APPLY)
3772 return NB_OK;
3773
3774 circuit = nb_running_get_entry(args->dnode, NULL, true);
3775 circuit->tilfa_link_fallback[1] =
3776 yang_dnode_get_bool(args->dnode, NULL);
3777
3778 area = circuit->area;
3779 if (area)
3780 lsp_regenerate_schedule(area, area->is_type, 0);
3781
3782 return NB_OK;
3783 }