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