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