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