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