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