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