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