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