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