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