]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_nb_config.c
zebra: Fix label manager memory leak (#5680)
[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
25#include "northbound.h"
26#include "linklist.h"
27#include "log.h"
28#include "bfd.h"
29#include "spf_backoff.h"
30#include "lib_errors.h"
31#include "vrf.h"
32
33#include "isisd/isisd.h"
34#include "isisd/isis_nb.h"
35#include "isisd/isis_common.h"
36#include "isisd/isis_bfd.h"
37#include "isisd/isis_circuit.h"
38#include "isisd/isis_lsp.h"
39#include "isisd/isis_dynhn.h"
40#include "isisd/isis_misc.h"
41#include "isisd/isis_csm.h"
42#include "isisd/isis_adjacency.h"
43#include "isisd/isis_spf.h"
44#include "isisd/isis_te.h"
45#include "isisd/isis_memory.h"
46#include "isisd/isis_mt.h"
47#include "isisd/isis_redist.h"
48
49/*
50 * XPath: /frr-isisd:isis/instance
51 */
52int isis_instance_create(enum nb_event event, const struct lyd_node *dnode,
53 union nb_resource *resource)
54{
55 struct isis_area *area;
56 const char *area_tag;
57
58 if (event != NB_EV_APPLY)
59 return NB_OK;
60
61 area_tag = yang_dnode_get_string(dnode, "./area-tag");
62 area = isis_area_lookup(area_tag);
63 if (area)
64 return NB_ERR_INCONSISTENCY;
65
66 area = isis_area_create(area_tag);
67 /* save area in dnode to avoid looking it up all the time */
68 nb_running_set_entry(dnode, area);
69
70 return NB_OK;
71}
72
73int isis_instance_destroy(enum nb_event event, const struct lyd_node *dnode)
74{
75 struct isis_area *area;
76
77 if (event != NB_EV_APPLY)
78 return NB_OK;
79
80 area = nb_running_unset_entry(dnode);
81 isis_area_destroy(area->area_tag);
82
83 return NB_OK;
84}
85
86/*
87 * XPath: /frr-isisd:isis/instance/is-type
88 */
89int isis_instance_is_type_modify(enum nb_event event,
90 const struct lyd_node *dnode,
91 union nb_resource *resource)
92{
93 struct isis_area *area;
94 int type;
95
96 if (event != NB_EV_APPLY)
97 return NB_OK;
98
99 area = nb_running_get_entry(dnode, NULL, true);
100 type = yang_dnode_get_enum(dnode, NULL);
101 isis_area_is_type_set(area, type);
102
103 return NB_OK;
104}
105
106/*
107 * XPath: /frr-isisd:isis/instance/area-address
108 */
109int isis_instance_area_address_create(enum nb_event event,
110 const struct lyd_node *dnode,
111 union nb_resource *resource)
112{
113 struct isis_area *area;
114 struct area_addr addr, *addrr = NULL, *addrp = NULL;
115 struct listnode *node;
116 uint8_t buff[255];
117 const char *net_title = yang_dnode_get_string(dnode, NULL);
118
119 switch (event) {
120 case NB_EV_VALIDATE:
121 addr.addr_len = dotformat2buff(buff, net_title);
122 memcpy(addr.area_addr, buff, addr.addr_len);
123 if (addr.area_addr[addr.addr_len - 1] != 0) {
124 flog_warn(
125 EC_LIB_NB_CB_CONFIG_VALIDATE,
126 "nsel byte (last byte) in area address must be 0");
127 return NB_ERR_VALIDATION;
128 }
129 if (isis->sysid_set) {
130 /* Check that the SystemID portions match */
131 if (memcmp(isis->sysid, GETSYSID((&addr)),
132 ISIS_SYS_ID_LEN)) {
133 flog_warn(
134 EC_LIB_NB_CB_CONFIG_VALIDATE,
135 "System ID must not change when defining additional area addresses");
136 return NB_ERR_VALIDATION;
137 }
138 }
139 break;
140 case NB_EV_PREPARE:
141 addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
142 addrr->addr_len = dotformat2buff(buff, net_title);
143 memcpy(addrr->area_addr, buff, addrr->addr_len);
144 resource->ptr = addrr;
145 break;
146 case NB_EV_ABORT:
147 XFREE(MTYPE_ISIS_AREA_ADDR, resource->ptr);
148 break;
149 case NB_EV_APPLY:
150 area = nb_running_get_entry(dnode, NULL, true);
151 addrr = resource->ptr;
152
153 if (isis->sysid_set == 0) {
154 /*
155 * First area address - get the SystemID for this router
156 */
157 memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
158 isis->sysid_set = 1;
159 } else {
160 /* check that we don't already have this address */
161 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
162 addrp)) {
163 if ((addrp->addr_len + ISIS_SYS_ID_LEN
164 + ISIS_NSEL_LEN)
165 != (addrr->addr_len))
166 continue;
167 if (!memcmp(addrp->area_addr, addrr->area_addr,
168 addrr->addr_len)) {
169 XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
170 return NB_OK; /* silent fail */
171 }
172 }
173 }
174
175 /*Forget the systemID part of the address */
176 addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
177 assert(area->area_addrs); /* to silence scan-build sillyness */
178 listnode_add(area->area_addrs, addrr);
179
180 /* only now we can safely generate our LSPs for this area */
181 if (listcount(area->area_addrs) > 0) {
182 if (area->is_type & IS_LEVEL_1)
183 lsp_generate(area, IS_LEVEL_1);
184 if (area->is_type & IS_LEVEL_2)
185 lsp_generate(area, IS_LEVEL_2);
186 }
187 break;
188 }
189
190 return NB_OK;
191}
192
193int isis_instance_area_address_destroy(enum nb_event event,
194 const struct lyd_node *dnode)
195{
196 struct area_addr addr, *addrp = NULL;
197 struct listnode *node;
198 uint8_t buff[255];
199 struct isis_area *area;
200 const char *net_title;
201
202 if (event != NB_EV_APPLY)
203 return NB_OK;
204
205 net_title = yang_dnode_get_string(dnode, NULL);
206 addr.addr_len = dotformat2buff(buff, net_title);
207 memcpy(addr.area_addr, buff, (int)addr.addr_len);
208 area = nb_running_get_entry(dnode, NULL, true);
209 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
210 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
211 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
212 break;
213 }
214 if (!addrp)
215 return NB_ERR_INCONSISTENCY;
216
217 listnode_delete(area->area_addrs, addrp);
218 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
219 /*
220 * Last area address - reset the SystemID for this router
221 */
222 if (listcount(area->area_addrs) == 0) {
223 memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
224 isis->sysid_set = 0;
225 if (isis->debugs & DEBUG_EVENTS)
226 zlog_debug("Router has no SystemID");
227 }
228
229 return NB_OK;
230}
231
232/*
233 * XPath: /frr-isisd:isis/instance/dynamic-hostname
234 */
235int isis_instance_dynamic_hostname_modify(enum nb_event event,
236 const struct lyd_node *dnode,
237 union nb_resource *resource)
238{
239 struct isis_area *area;
240
241 if (event != NB_EV_APPLY)
242 return NB_OK;
243
244 area = nb_running_get_entry(dnode, NULL, true);
245 isis_area_dynhostname_set(area, yang_dnode_get_bool(dnode, NULL));
246
247 return NB_OK;
248}
249
250/*
251 * XPath: /frr-isisd:isis/instance/attached
252 */
253int isis_instance_attached_modify(enum nb_event event,
254 const struct lyd_node *dnode,
255 union nb_resource *resource)
256{
257 struct isis_area *area;
258 bool attached;
259
260 if (event != NB_EV_APPLY)
261 return NB_OK;
262
263 area = nb_running_get_entry(dnode, NULL, true);
264 attached = yang_dnode_get_bool(dnode, NULL);
265 isis_area_attached_bit_set(area, attached);
266
267 return NB_OK;
268}
269
270/*
271 * XPath: /frr-isisd:isis/instance/overload
272 */
273int isis_instance_overload_modify(enum nb_event event,
274 const struct lyd_node *dnode,
275 union nb_resource *resource)
276{
277 struct isis_area *area;
278 bool overload;
279
280 if (event != NB_EV_APPLY)
281 return NB_OK;
282
283 area = nb_running_get_entry(dnode, NULL, true);
284 overload = yang_dnode_get_bool(dnode, NULL);
285 isis_area_overload_bit_set(area, overload);
286
287 return NB_OK;
288}
289
290/*
291 * XPath: /frr-isisd:isis/instance/metric-style
292 */
293int isis_instance_metric_style_modify(enum nb_event event,
294 const struct lyd_node *dnode,
295 union nb_resource *resource)
296{
297 struct isis_area *area;
298 bool old_metric, new_metric;
299 enum isis_metric_style metric_style = yang_dnode_get_enum(dnode, NULL);
300
301 if (event != NB_EV_APPLY)
302 return NB_OK;
303
304 area = nb_running_get_entry(dnode, NULL, true);
305 old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true;
306 new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true;
307 isis_area_metricstyle_set(area, old_metric, new_metric);
308
309 return NB_OK;
310}
311
312/*
313 * XPath: /frr-isisd:isis/instance/purge-originator
314 */
315int isis_instance_purge_originator_modify(enum nb_event event,
316 const struct lyd_node *dnode,
317 union nb_resource *resource)
318{
319 struct isis_area *area;
320
321 if (event != NB_EV_APPLY)
322 return NB_OK;
323
324 area = nb_running_get_entry(dnode, NULL, true);
325 area->purge_originator = yang_dnode_get_bool(dnode, NULL);
326
327 return NB_OK;
328}
329
330/*
331 * XPath: /frr-isisd:isis/instance/lsp/mtu
332 */
333int isis_instance_lsp_mtu_modify(enum nb_event event,
334 const struct lyd_node *dnode,
335 union nb_resource *resource)
336{
337 struct listnode *node;
338 struct isis_circuit *circuit;
339 uint16_t lsp_mtu = yang_dnode_get_uint16(dnode, NULL);
340 struct isis_area *area;
341
342 switch (event) {
343 case NB_EV_VALIDATE:
344 area = nb_running_get_entry(dnode, NULL, false);
345 if (!area)
346 break;
347 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
348 if (circuit->state != C_STATE_INIT
349 && circuit->state != C_STATE_UP)
350 continue;
351 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
352 flog_warn(
353 EC_LIB_NB_CB_CONFIG_VALIDATE,
354 "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
355 circuit->interface->name,
356 isis_circuit_pdu_size(circuit));
357 return NB_ERR_VALIDATION;
358 }
359 }
360 break;
361 case NB_EV_PREPARE:
362 case NB_EV_ABORT:
363 break;
364 case NB_EV_APPLY:
365 area = nb_running_get_entry(dnode, NULL, true);
366 isis_area_lsp_mtu_set(area, lsp_mtu);
367 break;
368 }
369
370 return NB_OK;
371}
372
373/*
374 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-1
375 */
376int isis_instance_lsp_refresh_interval_level_1_modify(
377 enum nb_event event, const struct lyd_node *dnode,
378 union nb_resource *resource)
379{
380 struct isis_area *area;
381 uint16_t refr_int;
382
383 if (event != NB_EV_APPLY)
384 return NB_OK;
385
386 refr_int = yang_dnode_get_uint16(dnode, NULL);
387 area = nb_running_get_entry(dnode, NULL, true);
388 isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int);
389
390 return NB_OK;
391}
392
393/*
394 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-2
395 */
396int isis_instance_lsp_refresh_interval_level_2_modify(
397 enum nb_event event, const struct lyd_node *dnode,
398 union nb_resource *resource)
399{
400 struct isis_area *area;
401 uint16_t refr_int;
402
403 if (event != NB_EV_APPLY)
404 return NB_OK;
405
406 refr_int = yang_dnode_get_uint16(dnode, NULL);
407 area = nb_running_get_entry(dnode, NULL, true);
408 isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int);
409
410 return NB_OK;
411}
412
413/*
414 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-1
415 */
416int isis_instance_lsp_maximum_lifetime_level_1_modify(
417 enum nb_event event, const struct lyd_node *dnode,
418 union nb_resource *resource)
419{
420 struct isis_area *area;
421 uint16_t max_lt;
422
423 if (event != NB_EV_APPLY)
424 return NB_OK;
425
426 max_lt = yang_dnode_get_uint16(dnode, NULL);
427 area = nb_running_get_entry(dnode, NULL, true);
428 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt);
429
430 return NB_OK;
431}
432
433/*
434 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-2
435 */
436int isis_instance_lsp_maximum_lifetime_level_2_modify(
437 enum nb_event event, const struct lyd_node *dnode,
438 union nb_resource *resource)
439{
440 struct isis_area *area;
441 uint16_t max_lt;
442
443 if (event != NB_EV_APPLY)
444 return NB_OK;
445
446 max_lt = yang_dnode_get_uint16(dnode, NULL);
447 area = nb_running_get_entry(dnode, NULL, true);
448 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt);
449
450 return NB_OK;
451}
452
453/*
454 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-1
455 */
456int isis_instance_lsp_generation_interval_level_1_modify(
457 enum nb_event event, const struct lyd_node *dnode,
458 union nb_resource *resource)
459{
460 struct isis_area *area;
461 uint16_t gen_int;
462
463 if (event != NB_EV_APPLY)
464 return NB_OK;
465
466 gen_int = yang_dnode_get_uint16(dnode, NULL);
467 area = nb_running_get_entry(dnode, NULL, true);
468 area->lsp_gen_interval[0] = gen_int;
469
470 return NB_OK;
471}
472
473/*
474 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-2
475 */
476int isis_instance_lsp_generation_interval_level_2_modify(
477 enum nb_event event, const struct lyd_node *dnode,
478 union nb_resource *resource)
479{
480 struct isis_area *area;
481 uint16_t gen_int;
482
483 if (event != NB_EV_APPLY)
484 return NB_OK;
485
486 gen_int = yang_dnode_get_uint16(dnode, NULL);
487 area = nb_running_get_entry(dnode, NULL, true);
488 area->lsp_gen_interval[1] = gen_int;
489
490 return NB_OK;
491}
492
493/*
494 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
495 */
496void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode)
497{
498 long init_delay = yang_dnode_get_uint16(dnode, "./init-delay");
499 long short_delay = yang_dnode_get_uint16(dnode, "./short-delay");
500 long long_delay = yang_dnode_get_uint16(dnode, "./long-delay");
501 long holddown = yang_dnode_get_uint16(dnode, "./hold-down");
502 long timetolearn = yang_dnode_get_uint16(dnode, "./time-to-learn");
503 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
504 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
505 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
506
507 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
508 spf_backoff_free(area->spf_delay_ietf[0]);
509 area->spf_delay_ietf[0] =
510 spf_backoff_new(master, buf, init_delay, short_delay,
511 long_delay, holddown, timetolearn);
512
513 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
514 spf_backoff_free(area->spf_delay_ietf[1]);
515 area->spf_delay_ietf[1] =
516 spf_backoff_new(master, buf, init_delay, short_delay,
517 long_delay, holddown, timetolearn);
518
519 XFREE(MTYPE_TMP, buf);
520}
521
522int isis_instance_spf_ietf_backoff_delay_create(enum nb_event event,
523 const struct lyd_node *dnode,
524 union nb_resource *resource)
525{
526 /* All the work is done in the apply_finish */
527 return NB_OK;
528}
529
530int isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event,
531 const struct lyd_node *dnode)
532{
533 struct isis_area *area;
534
535 if (event != NB_EV_APPLY)
536 return NB_OK;
537
538 area = nb_running_get_entry(dnode, NULL, true);
539 spf_backoff_free(area->spf_delay_ietf[0]);
540 spf_backoff_free(area->spf_delay_ietf[1]);
541 area->spf_delay_ietf[0] = NULL;
542 area->spf_delay_ietf[1] = NULL;
543
544 return NB_OK;
545}
546
547/*
548 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
549 */
550int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
551 enum nb_event event, const struct lyd_node *dnode,
552 union nb_resource *resource)
553{
554 /* All the work is done in the apply_finish */
555 return NB_OK;
556}
557
558/*
559 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
560 */
561int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
562 enum nb_event event, const struct lyd_node *dnode,
563 union nb_resource *resource)
564{
565 /* All the work is done in the apply_finish */
566 return NB_OK;
567}
568
569/*
570 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
571 */
572int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
573 enum nb_event event, const struct lyd_node *dnode,
574 union nb_resource *resource)
575{
576 /* All the work is done in the apply_finish */
577 return NB_OK;
578}
579
580/*
581 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
582 */
583int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
584 enum nb_event event, const struct lyd_node *dnode,
585 union nb_resource *resource)
586{
587 /* All the work is done in the apply_finish */
588 return NB_OK;
589}
590
591/*
592 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
593 */
594int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
595 enum nb_event event, const struct lyd_node *dnode,
596 union nb_resource *resource)
597{
598 /* All the work is done in the apply_finish */
599 return NB_OK;
600}
601
602/*
603 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
604 */
605int isis_instance_spf_minimum_interval_level_1_modify(
606 enum nb_event event, const struct lyd_node *dnode,
607 union nb_resource *resource)
608{
609 struct isis_area *area;
610
611 if (event != NB_EV_APPLY)
612 return NB_OK;
613
614 area = nb_running_get_entry(dnode, NULL, true);
615 area->min_spf_interval[0] = yang_dnode_get_uint16(dnode, NULL);
616
617 return NB_OK;
618}
619
620/*
621 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
622 */
623int isis_instance_spf_minimum_interval_level_2_modify(
624 enum nb_event event, const struct lyd_node *dnode,
625 union nb_resource *resource)
626{
627 struct isis_area *area;
628
629 if (event != NB_EV_APPLY)
630 return NB_OK;
631
632 area = nb_running_get_entry(dnode, NULL, true);
633 area->min_spf_interval[1] = yang_dnode_get_uint16(dnode, NULL);
634
635 return NB_OK;
636}
637
638/*
639 * XPath: /frr-isisd:isis/instance/area-password
640 */
641void area_password_apply_finish(const struct lyd_node *dnode)
642{
643 const char *password = yang_dnode_get_string(dnode, "./password");
644 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
645 int pass_type = yang_dnode_get_enum(dnode, "./password-type");
646 uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
647
648 switch (pass_type) {
649 case ISIS_PASSWD_TYPE_CLEARTXT:
650 isis_area_passwd_cleartext_set(area, IS_LEVEL_1, password,
651 snp_auth);
652 break;
653 case ISIS_PASSWD_TYPE_HMAC_MD5:
654 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_1, password,
655 snp_auth);
656 break;
657 }
658}
659
660int isis_instance_area_password_create(enum nb_event event,
661 const struct lyd_node *dnode,
662 union nb_resource *resource)
663{
664 /* actual setting is done in apply_finish */
665 return NB_OK;
666}
667
668int isis_instance_area_password_destroy(enum nb_event event,
669 const struct lyd_node *dnode)
670{
671 struct isis_area *area;
672
673 if (event != NB_EV_APPLY)
674 return NB_OK;
675
676 area = nb_running_get_entry(dnode, NULL, true);
677 isis_area_passwd_unset(area, IS_LEVEL_1);
678
679 return NB_OK;
680}
681
682/*
683 * XPath: /frr-isisd:isis/instance/area-password/password
684 */
685int isis_instance_area_password_password_modify(enum nb_event event,
686 const struct lyd_node *dnode,
687 union nb_resource *resource)
688{
689 /* actual setting is done in apply_finish */
690 return NB_OK;
691}
692
693/*
694 * XPath: /frr-isisd:isis/instance/area-password/password-type
695 */
696int isis_instance_area_password_password_type_modify(
697 enum nb_event event, const struct lyd_node *dnode,
698 union nb_resource *resource)
699{
700 /* actual setting is done in apply_finish */
701 return NB_OK;
702}
703
704/*
705 * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
706 */
707int isis_instance_area_password_authenticate_snp_modify(
708 enum nb_event event, const struct lyd_node *dnode,
709 union nb_resource *resource)
710{
711 /* actual setting is done in apply_finish */
712 return NB_OK;
713}
714
715/*
716 * XPath: /frr-isisd:isis/instance/domain-password
717 */
718void domain_password_apply_finish(const struct lyd_node *dnode)
719{
720 const char *password = yang_dnode_get_string(dnode, "./password");
721 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
722 int pass_type = yang_dnode_get_enum(dnode, "./password-type");
723 uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
724
725 switch (pass_type) {
726 case ISIS_PASSWD_TYPE_CLEARTXT:
727 isis_area_passwd_cleartext_set(area, IS_LEVEL_2, password,
728 snp_auth);
729 break;
730 case ISIS_PASSWD_TYPE_HMAC_MD5:
731 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_2, password,
732 snp_auth);
733 break;
734 }
735}
736
737int isis_instance_domain_password_create(enum nb_event event,
738 const struct lyd_node *dnode,
739 union nb_resource *resource)
740{
741 /* actual setting is done in apply_finish */
742 return NB_OK;
743}
744
745int isis_instance_domain_password_destroy(enum nb_event event,
746 const struct lyd_node *dnode)
747{
748 struct isis_area *area;
749
750 if (event != NB_EV_APPLY)
751 return NB_OK;
752
753 area = nb_running_get_entry(dnode, NULL, true);
754 isis_area_passwd_unset(area, IS_LEVEL_2);
755
756 return NB_OK;
757}
758
759/*
760 * XPath: /frr-isisd:isis/instance/domain-password/password
761 */
762int isis_instance_domain_password_password_modify(enum nb_event event,
763 const struct lyd_node *dnode,
764 union nb_resource *resource)
765{
766 /* actual setting is done in apply_finish */
767 return NB_OK;
768}
769
770/*
771 * XPath: /frr-isisd:isis/instance/domain-password/password-type
772 */
773int isis_instance_domain_password_password_type_modify(
774 enum nb_event event, const struct lyd_node *dnode,
775 union nb_resource *resource)
776{
777 /* actual setting is done in apply_finish */
778 return NB_OK;
779}
780
781/*
782 * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
783 */
784int isis_instance_domain_password_authenticate_snp_modify(
785 enum nb_event event, const struct lyd_node *dnode,
786 union nb_resource *resource)
787{
788 /* actual setting is done in apply_finish */
789 return NB_OK;
790}
791
792/*
793 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
794 */
795void default_info_origin_apply_finish(const struct lyd_node *dnode, int family)
796{
797 int originate_type = DEFAULT_ORIGINATE;
798 unsigned long metric = 0;
799 const char *routemap = NULL;
800 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
801 int level = yang_dnode_get_enum(dnode, "./level");
802
803 if (yang_dnode_get_bool(dnode, "./always")) {
804 originate_type = DEFAULT_ORIGINATE_ALWAYS;
805 } else if (family == AF_INET6) {
806 zlog_warn(
807 "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
808 __func__);
809 }
810
811 if (yang_dnode_exists(dnode, "./metric"))
812 metric = yang_dnode_get_uint32(dnode, "./metric");
813 if (yang_dnode_exists(dnode, "./route-map"))
814 routemap = yang_dnode_get_string(dnode, "./route-map");
815
816 isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
817 originate_type);
818}
819
820void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
821{
822 default_info_origin_apply_finish(dnode, AF_INET);
823}
824
825void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
826{
827 default_info_origin_apply_finish(dnode, AF_INET6);
828}
829
830int isis_instance_default_information_originate_ipv4_create(
831 enum nb_event event, const struct lyd_node *dnode,
832 union nb_resource *resource)
833{
834 /* It's all done by default_info_origin_apply_finish */
835 return NB_OK;
836}
837
838int isis_instance_default_information_originate_ipv4_destroy(
839 enum nb_event event, const struct lyd_node *dnode)
840{
841 struct isis_area *area;
842 int level;
843
844 if (event != NB_EV_APPLY)
845 return NB_OK;
846
847 area = nb_running_get_entry(dnode, NULL, true);
848 level = yang_dnode_get_enum(dnode, "./level");
849 isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
850
851 return NB_OK;
852}
853
854/*
855 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
856 */
857int isis_instance_default_information_originate_ipv4_always_modify(
858 enum nb_event event, const struct lyd_node *dnode,
859 union nb_resource *resource)
860{
861 /* It's all done by default_info_origin_apply_finish */
862 return NB_OK;
863}
864
865/*
866 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
867 */
868int isis_instance_default_information_originate_ipv4_route_map_modify(
869 enum nb_event event, const struct lyd_node *dnode,
870 union nb_resource *resource)
871{
872 /* It's all done by default_info_origin_apply_finish */
873 return NB_OK;
874}
875
876int isis_instance_default_information_originate_ipv4_route_map_destroy(
877 enum nb_event event, const struct lyd_node *dnode)
878{
879 /* It's all done by default_info_origin_apply_finish */
880 return NB_OK;
881}
882
883/*
884 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
885 */
886int isis_instance_default_information_originate_ipv4_metric_modify(
887 enum nb_event event, const struct lyd_node *dnode,
888 union nb_resource *resource)
889{
890 /* It's all done by default_info_origin_apply_finish */
891 return NB_OK;
892}
893
894/*
895 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
896 */
897int isis_instance_default_information_originate_ipv6_create(
898 enum nb_event event, const struct lyd_node *dnode,
899 union nb_resource *resource)
900{
901 /* It's all done by default_info_origin_apply_finish */
902 return NB_OK;
903}
904
905int isis_instance_default_information_originate_ipv6_destroy(
906 enum nb_event event, const struct lyd_node *dnode)
907{
908 struct isis_area *area;
909 int level;
910
911 if (event != NB_EV_APPLY)
912 return NB_OK;
913
914 area = nb_running_get_entry(dnode, NULL, true);
915 level = yang_dnode_get_enum(dnode, "./level");
916 isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
917
918 return NB_OK;
919}
920
921/*
922 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
923 */
924int isis_instance_default_information_originate_ipv6_always_modify(
925 enum nb_event event, const struct lyd_node *dnode,
926 union nb_resource *resource)
927{
928 /* It's all done by default_info_origin_apply_finish */
929 return NB_OK;
930}
931
932/*
933 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
934 */
935int isis_instance_default_information_originate_ipv6_route_map_modify(
936 enum nb_event event, const struct lyd_node *dnode,
937 union nb_resource *resource)
938{
939 /* It's all done by default_info_origin_apply_finish */
940 return NB_OK;
941}
942
943int isis_instance_default_information_originate_ipv6_route_map_destroy(
944 enum nb_event event, const struct lyd_node *dnode)
945{
946 /* It's all done by default_info_origin_apply_finish */
947 return NB_OK;
948}
949
950/*
951 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
952 */
953int isis_instance_default_information_originate_ipv6_metric_modify(
954 enum nb_event event, const struct lyd_node *dnode,
955 union nb_resource *resource)
956{
957 /* It's all done by default_info_origin_apply_finish */
958 return NB_OK;
959}
960
961/*
962 * XPath: /frr-isisd:isis/instance/redistribute/ipv4
963 */
964void redistribute_apply_finish(const struct lyd_node *dnode, int family)
965{
966 assert(family == AF_INET || family == AF_INET6);
967 int type, level;
968 unsigned long metric = 0;
969 const char *routemap = NULL;
970 struct isis_area *area;
971
972 type = yang_dnode_get_enum(dnode, "./protocol");
973 level = yang_dnode_get_enum(dnode, "./level");
974 area = nb_running_get_entry(dnode, NULL, true);
975
976 if (yang_dnode_exists(dnode, "./metric"))
977 metric = yang_dnode_get_uint32(dnode, "./metric");
978 if (yang_dnode_exists(dnode, "./route-map"))
979 routemap = yang_dnode_get_string(dnode, "./route-map");
980
981 isis_redist_set(area, level, family, type, metric, routemap, 0);
982}
983
984void redistribute_ipv4_apply_finish(const struct lyd_node *dnode)
985{
986 redistribute_apply_finish(dnode, AF_INET);
987}
988
989void redistribute_ipv6_apply_finish(const struct lyd_node *dnode)
990{
991 redistribute_apply_finish(dnode, AF_INET6);
992}
993
994int isis_instance_redistribute_ipv4_create(enum nb_event event,
995 const struct lyd_node *dnode,
996 union nb_resource *resource)
997{
998 /* It's all done by redistribute_apply_finish */
999 return NB_OK;
1000}
1001
1002int isis_instance_redistribute_ipv4_destroy(enum nb_event event,
1003 const struct lyd_node *dnode)
1004{
1005 struct isis_area *area;
1006 int level, type;
1007
1008 if (event != NB_EV_APPLY)
1009 return NB_OK;
1010
1011 area = nb_running_get_entry(dnode, NULL, true);
1012 level = yang_dnode_get_enum(dnode, "./level");
1013 type = yang_dnode_get_enum(dnode, "./protocol");
1014 isis_redist_unset(area, level, AF_INET, type);
1015
1016 return NB_OK;
1017}
1018
1019/*
1020 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
1021 */
1022int isis_instance_redistribute_ipv4_route_map_modify(
1023 enum nb_event event, const struct lyd_node *dnode,
1024 union nb_resource *resource)
1025{
1026 /* It's all done by redistribute_apply_finish */
1027 return NB_OK;
1028}
1029
1030int isis_instance_redistribute_ipv4_route_map_destroy(
1031 enum nb_event event, const struct lyd_node *dnode)
1032{
1033 /* It's all done by redistribute_apply_finish */
1034 return NB_OK;
1035}
1036
1037/*
1038 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
1039 */
1040int isis_instance_redistribute_ipv4_metric_modify(enum nb_event event,
1041 const struct lyd_node *dnode,
1042 union nb_resource *resource)
1043{
1044 /* It's all done by redistribute_apply_finish */
1045 return NB_OK;
1046}
1047
1048/*
1049 * XPath: /frr-isisd:isis/instance/redistribute/ipv6
1050 */
1051int isis_instance_redistribute_ipv6_create(enum nb_event event,
1052 const struct lyd_node *dnode,
1053 union nb_resource *resource)
1054{
1055 /* It's all done by redistribute_apply_finish */
1056 return NB_OK;
1057}
1058
1059int isis_instance_redistribute_ipv6_destroy(enum nb_event event,
1060 const struct lyd_node *dnode)
1061{
1062 struct isis_area *area;
1063 int level, type;
1064
1065 if (event != NB_EV_APPLY)
1066 return NB_OK;
1067
1068 area = nb_running_get_entry(dnode, NULL, true);
1069 level = yang_dnode_get_enum(dnode, "./level");
1070 type = yang_dnode_get_enum(dnode, "./protocol");
1071 isis_redist_unset(area, level, AF_INET6, type);
1072
1073 return NB_OK;
1074}
1075
1076/*
1077 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
1078 */
1079int isis_instance_redistribute_ipv6_route_map_modify(
1080 enum nb_event event, const struct lyd_node *dnode,
1081 union nb_resource *resource)
1082{
1083 /* It's all done by redistribute_apply_finish */
1084 return NB_OK;
1085}
1086
1087int isis_instance_redistribute_ipv6_route_map_destroy(
1088 enum nb_event event, const struct lyd_node *dnode)
1089{
1090 /* It's all done by redistribute_apply_finish */
1091 return NB_OK;
1092}
1093
1094/*
1095 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
1096 */
1097int isis_instance_redistribute_ipv6_metric_modify(enum nb_event event,
1098 const struct lyd_node *dnode,
1099 union nb_resource *resource)
1100{
1101 /* It's all done by redistribute_apply_finish */
1102 return NB_OK;
1103}
1104
1105/*
1106 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
1107 */
1108static int isis_multi_topology_common(enum nb_event event,
1109 const struct lyd_node *dnode,
1110 const char *topology, bool create)
1111{
1112 struct isis_area *area;
1113 struct isis_area_mt_setting *setting;
1114 uint16_t mtid = isis_str2mtid(topology);
1115
1116 switch (event) {
1117 case NB_EV_VALIDATE:
1118 if (mtid == (uint16_t)-1) {
1119 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1120 "Unknown topology %s", topology);
1121 return NB_ERR_VALIDATION;
1122 }
1123 break;
1124 case NB_EV_PREPARE:
1125 case NB_EV_ABORT:
1126 break;
1127 case NB_EV_APPLY:
1128 area = nb_running_get_entry(dnode, NULL, true);
1129 setting = area_get_mt_setting(area, mtid);
1130 setting->enabled = create;
1131 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1132 break;
1133 }
1134
1135 return NB_OK;
1136}
1137
1138static int isis_multi_topology_overload_common(enum nb_event event,
1139 const struct lyd_node *dnode,
1140 const char *topology)
1141{
1142 struct isis_area *area;
1143 struct isis_area_mt_setting *setting;
1144 uint16_t mtid = isis_str2mtid(topology);
1145
1146 /* validation is done in isis_multi_topology_common */
1147 if (event != NB_EV_APPLY)
1148 return NB_OK;
1149
1150 area = nb_running_get_entry(dnode, NULL, true);
1151 setting = area_get_mt_setting(area, mtid);
1152 setting->overload = yang_dnode_get_bool(dnode, NULL);
1153 if (setting->enabled)
1154 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1155
1156 return NB_OK;
1157}
1158
1159int isis_instance_multi_topology_ipv4_multicast_create(
1160 enum nb_event event, const struct lyd_node *dnode,
1161 union nb_resource *resource)
1162{
1163 return isis_multi_topology_common(event, dnode, "ipv4-multicast", true);
1164}
1165
1166int isis_instance_multi_topology_ipv4_multicast_destroy(
1167 enum nb_event event, const struct lyd_node *dnode)
1168{
1169 return isis_multi_topology_common(event, dnode, "ipv4-multicast",
1170 false);
1171}
1172
1173/*
1174 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
1175 */
1176int isis_instance_multi_topology_ipv4_multicast_overload_modify(
1177 enum nb_event event, const struct lyd_node *dnode,
1178 union nb_resource *resource)
1179{
1180 return isis_multi_topology_overload_common(event, dnode,
1181 "ipv4-multicast");
1182}
1183
1184/*
1185 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
1186 */
1187int isis_instance_multi_topology_ipv4_management_create(
1188 enum nb_event event, const struct lyd_node *dnode,
1189 union nb_resource *resource)
1190{
1191 return isis_multi_topology_common(event, dnode, "ipv4-mgmt", true);
1192}
1193
1194int isis_instance_multi_topology_ipv4_management_destroy(
1195 enum nb_event event, const struct lyd_node *dnode)
1196{
1197 return isis_multi_topology_common(event, dnode, "ipv4-mgmt", false);
1198}
1199
1200/*
1201 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
1202 */
1203int isis_instance_multi_topology_ipv4_management_overload_modify(
1204 enum nb_event event, const struct lyd_node *dnode,
1205 union nb_resource *resource)
1206{
1207 return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt");
1208}
1209
1210/*
1211 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
1212 */
1213int isis_instance_multi_topology_ipv6_unicast_create(
1214 enum nb_event event, const struct lyd_node *dnode,
1215 union nb_resource *resource)
1216{
1217 return isis_multi_topology_common(event, dnode, "ipv6-unicast", true);
1218}
1219
1220int isis_instance_multi_topology_ipv6_unicast_destroy(
1221 enum nb_event event, const struct lyd_node *dnode)
1222{
1223 return isis_multi_topology_common(event, dnode, "ipv6-unicast", false);
1224}
1225
1226/*
1227 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
1228 */
1229int isis_instance_multi_topology_ipv6_unicast_overload_modify(
1230 enum nb_event event, const struct lyd_node *dnode,
1231 union nb_resource *resource)
1232{
1233 return isis_multi_topology_overload_common(event, dnode,
1234 "ipv6-unicast");
1235}
1236
1237/*
1238 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
1239 */
1240int isis_instance_multi_topology_ipv6_multicast_create(
1241 enum nb_event event, const struct lyd_node *dnode,
1242 union nb_resource *resource)
1243{
1244 return isis_multi_topology_common(event, dnode, "ipv6-multicast", true);
1245}
1246
1247int isis_instance_multi_topology_ipv6_multicast_destroy(
1248 enum nb_event event, const struct lyd_node *dnode)
1249{
1250 return isis_multi_topology_common(event, dnode, "ipv6-multicast",
1251 false);
1252}
1253
1254/*
1255 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
1256 */
1257int isis_instance_multi_topology_ipv6_multicast_overload_modify(
1258 enum nb_event event, const struct lyd_node *dnode,
1259 union nb_resource *resource)
1260{
1261 return isis_multi_topology_overload_common(event, dnode,
1262 "ipv6-multicast");
1263}
1264
1265/*
1266 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
1267 */
1268int isis_instance_multi_topology_ipv6_management_create(
1269 enum nb_event event, const struct lyd_node *dnode,
1270 union nb_resource *resource)
1271{
1272 return isis_multi_topology_common(event, dnode, "ipv6-mgmt", true);
1273}
1274
1275int isis_instance_multi_topology_ipv6_management_destroy(
1276 enum nb_event event, const struct lyd_node *dnode)
1277{
1278 return isis_multi_topology_common(event, dnode, "ipv6-mgmt", false);
1279}
1280
1281/*
1282 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
1283 */
1284int isis_instance_multi_topology_ipv6_management_overload_modify(
1285 enum nb_event event, const struct lyd_node *dnode,
1286 union nb_resource *resource)
1287{
1288 return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt");
1289}
1290
1291/*
1292 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
1293 */
1294int isis_instance_multi_topology_ipv6_dstsrc_create(
1295 enum nb_event event, const struct lyd_node *dnode,
1296 union nb_resource *resource)
1297{
1298 return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", true);
1299}
1300
1301int isis_instance_multi_topology_ipv6_dstsrc_destroy(
1302 enum nb_event event, const struct lyd_node *dnode)
1303{
1304 return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", false);
1305}
1306
1307/*
1308 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
1309 */
1310int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
1311 enum nb_event event, const struct lyd_node *dnode,
1312 union nb_resource *resource)
1313{
1314 return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc");
1315}
1316
1317/*
1318 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1319 */
1320int isis_instance_log_adjacency_changes_modify(enum nb_event event,
1321 const struct lyd_node *dnode,
1322 union nb_resource *resource)
1323{
1324 struct isis_area *area;
1325 bool log = yang_dnode_get_bool(dnode, NULL);
1326
1327 if (event != NB_EV_APPLY)
1328 return NB_OK;
1329
1330 area = nb_running_get_entry(dnode, NULL, true);
1331 area->log_adj_changes = log ? 1 : 0;
1332
1333 return NB_OK;
1334}
1335
1336/*
1337 * XPath: /frr-isisd:isis/instance/mpls-te
1338 */
1339int isis_instance_mpls_te_create(enum nb_event event,
1340 const struct lyd_node *dnode,
1341 union nb_resource *resource)
1342{
1343 struct listnode *node;
1344 struct isis_area *area;
1345 struct isis_circuit *circuit;
1346
1347 if (event != NB_EV_APPLY)
1348 return NB_OK;
1349
1350 area = nb_running_get_entry(dnode, NULL, true);
1351 if (area->mta == NULL) {
1352
1353 struct mpls_te_area *new;
1354
1355 zlog_debug("ISIS-TE(%s): Initialize MPLS Traffic Engineering",
1356 area->area_tag);
1357
1358 new = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_area));
1359
1360 /* Initialize MPLS_TE structure */
1361 new->status = enable;
1362 new->level = 0;
1363 new->inter_as = off;
1364 new->interas_areaid.s_addr = 0;
1365 new->router_id.s_addr = 0;
1366
1367 area->mta = new;
1368 } else {
1369 area->mta->status = enable;
1370 }
1371
1372 /* Update Extended TLVs according to Interface link parameters */
1373 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
1374 isis_link_params_update(circuit, circuit->interface);
1375
1376 /* Reoriginate STD_TE & GMPLS circuits */
1377 lsp_regenerate_schedule(area, area->is_type, 0);
1378
1379 return NB_OK;
1380}
1381
1382int isis_instance_mpls_te_destroy(enum nb_event event,
1383 const struct lyd_node *dnode)
1384{
1385 struct listnode *node;
1386 struct isis_area *area;
1387 struct isis_circuit *circuit;
1388
1389 if (event != NB_EV_APPLY)
1390 return NB_OK;
1391
1392 area = nb_running_get_entry(dnode, NULL, true);
1393 if (IS_MPLS_TE(area->mta))
1394 area->mta->status = disable;
1395 else
1396 return NB_OK;
1397
1398 /* Flush LSP if circuit engage */
1399 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
1400 if (!IS_EXT_TE(circuit->ext))
1401 continue;
1402
1403 /* disable MPLS_TE Circuit keeping SR one's */
1404 if (IS_SUBTLV(circuit->ext, EXT_ADJ_SID))
1405 circuit->ext->status = EXT_ADJ_SID;
1406 else if (IS_SUBTLV(circuit->ext, EXT_LAN_ADJ_SID))
1407 circuit->ext->status = EXT_LAN_ADJ_SID;
1408 else
1409 circuit->ext->status = 0;
1410 }
1411
1412 /* Reoriginate STD_TE & GMPLS circuits */
1413 lsp_regenerate_schedule(area, area->is_type, 0);
1414
1415 zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
1416 area->area_tag);
1417
1418 return NB_OK;
1419}
1420
1421/*
1422 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
1423 */
1424int isis_instance_mpls_te_router_address_modify(enum nb_event event,
1425 const struct lyd_node *dnode,
1426 union nb_resource *resource)
1427{
1428 struct in_addr value;
1429 struct isis_area *area;
1430
1431 if (event != NB_EV_APPLY)
1432 return NB_OK;
1433
1434 area = nb_running_get_entry(dnode, NULL, true);
1435 /* only proceed if MPLS-TE is enabled */
1436 if (!IS_MPLS_TE(area->mta))
1437 return NB_OK;
1438
1439 /* Update Area Router ID */
1440 yang_dnode_get_ipv4(&value, dnode, NULL);
1441 area->mta->router_id.s_addr = value.s_addr;
1442
1443 /* And re-schedule LSP update */
1444 lsp_regenerate_schedule(area, area->is_type, 0);
1445
1446 return NB_OK;
1447}
1448
1449int isis_instance_mpls_te_router_address_destroy(enum nb_event event,
1450 const struct lyd_node *dnode)
1451{
1452 struct isis_area *area;
1453
1454 if (event != NB_EV_APPLY)
1455 return NB_OK;
1456
1457 area = nb_running_get_entry(dnode, NULL, true);
1458 /* only proceed if MPLS-TE is enabled */
1459 if (!IS_MPLS_TE(area->mta))
1460 return NB_OK;
1461
1462 /* Reset Area Router ID */
1463 area->mta->router_id.s_addr = INADDR_ANY;
1464
1465 /* And re-schedule LSP update */
1466 lsp_regenerate_schedule(area, area->is_type, 0);
1467
1468 return NB_OK;
1469}
1470
1471/*
1472 * XPath: /frr-interface:lib/interface/frr-isisd:isis
1473 */
1474int lib_interface_isis_create(enum nb_event event, const struct lyd_node *dnode,
1475 union nb_resource *resource)
1476{
1477 struct isis_area *area;
1478 struct interface *ifp;
1479 struct isis_circuit *circuit;
1480 const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
1481 uint32_t min_mtu, actual_mtu;
1482
1483 switch (event) {
1484 case NB_EV_PREPARE:
1485 case NB_EV_ABORT:
1486 break;
1487 case NB_EV_VALIDATE:
1488 /* check if interface mtu is sufficient. If the area has not
1489 * been created yet, assume default MTU for the area
1490 */
1491 ifp = nb_running_get_entry(dnode, NULL, false);
1492 /* zebra might not know yet about the MTU - nothing we can do */
1493 if (!ifp || ifp->mtu == 0)
1494 break;
1495 actual_mtu =
1496 if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
1497 area = isis_area_lookup(area_tag);
1498 if (area)
1499 min_mtu = area->lsp_mtu;
1500 else
1501#ifndef FABRICD
1502 min_mtu = yang_get_default_uint16(
1503 "/frr-isisd:isis/instance/lsp/mtu");
1504#else
1505 min_mtu = DEFAULT_LSP_MTU;
1506#endif /* ifndef FABRICD */
1507 if (actual_mtu < min_mtu) {
1508 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1509 "Interface %s has MTU %" PRIu32
1510 ", minimum MTU for the area is %" PRIu32 "",
1511 ifp->name, actual_mtu, min_mtu);
1512 return NB_ERR_VALIDATION;
1513 }
1514 break;
1515 case NB_EV_APPLY:
1516 area = isis_area_lookup(area_tag);
1517 /* The area should have already be created. We are
1518 * setting the priority of the global isis area creation
1519 * slightly lower, so it should be executed first, but I
1520 * cannot rely on that so here I have to check.
1521 */
1522 if (!area) {
1523 flog_err(
1524 EC_LIB_NB_CB_CONFIG_APPLY,
1525 "%s: attempt to create circuit for area %s before the area has been created",
1526 __func__, area_tag);
1527 abort();
1528 }
1529
1530 ifp = nb_running_get_entry(dnode, NULL, true);
1531 circuit = isis_circuit_create(area, ifp);
1532 assert(circuit
1533 && (circuit->state == C_STATE_CONF
1534 || circuit->state == C_STATE_UP));
1535 nb_running_set_entry(dnode, circuit);
1536 break;
1537 }
1538
1539 return NB_OK;
1540}
1541
1542int lib_interface_isis_destroy(enum nb_event event,
1543 const struct lyd_node *dnode)
1544{
1545 struct isis_circuit *circuit;
1546
1547 if (event != NB_EV_APPLY)
1548 return NB_OK;
1549
1550 circuit = nb_running_unset_entry(dnode);
1551 if (!circuit)
1552 return NB_ERR_INCONSISTENCY;
2a1c520e 1553
d38a3cb2
EDP
1554 /* disable both AFs for this circuit. this will also update the
1555 * CSM state by sending an ISIS_DISABLED signal. If there is no
1556 * area associated to the circuit there is nothing to do
1557 */
1558 if (circuit->area)
1559 isis_circuit_af_set(circuit, false, false);
2a1c520e
RW
1560 return NB_OK;
1561}
1562
1563/*
1564 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1565 */
1566int lib_interface_isis_area_tag_modify(enum nb_event event,
1567 const struct lyd_node *dnode,
1568 union nb_resource *resource)
1569{
1570 struct isis_circuit *circuit;
1571 struct interface *ifp;
1572 struct vrf *vrf;
1573 const char *area_tag, *ifname, *vrfname;
1574
1575 if (event == NB_EV_VALIDATE) {
1576 /* libyang doesn't like relative paths across module boundaries
1577 */
1578 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1579 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1580 vrf = vrf_lookup_by_name(vrfname);
1581 assert(vrf);
1582 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1583 if (!ifp)
1584 return NB_OK;
1585 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1586 area_tag = yang_dnode_get_string(dnode, NULL);
1587 if (circuit && circuit->area && circuit->area->area_tag
1588 && strcmp(circuit->area->area_tag, area_tag)) {
1589 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1590 "ISIS circuit is already defined on %s",
1591 circuit->area->area_tag);
1592 return NB_ERR_VALIDATION;
1593 }
1594 }
1595
1596 return NB_OK;
1597}
1598
1599/*
1600 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1601 */
1602int lib_interface_isis_circuit_type_modify(enum nb_event event,
1603 const struct lyd_node *dnode,
1604 union nb_resource *resource)
1605{
1606 int circ_type = yang_dnode_get_enum(dnode, NULL);
1607 struct isis_circuit *circuit;
1608 struct interface *ifp;
1609 struct vrf *vrf;
1610 const char *ifname, *vrfname;
1611
1612 switch (event) {
1613 case NB_EV_VALIDATE:
1614 /* libyang doesn't like relative paths across module boundaries
1615 */
1616 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1617 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1618 vrf = vrf_lookup_by_name(vrfname);
1619 assert(vrf);
1620 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1621 if (!ifp)
1622 break;
1623 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1624 if (circuit && circuit->state == C_STATE_UP
1625 && circuit->area->is_type != IS_LEVEL_1_AND_2
1626 && circuit->area->is_type != circ_type) {
1627 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1628 "Invalid circuit level for area %s",
1629 circuit->area->area_tag);
1630 return NB_ERR_VALIDATION;
1631 }
1632 break;
1633 case NB_EV_PREPARE:
1634 case NB_EV_ABORT:
1635 break;
1636 case NB_EV_APPLY:
1637 circuit = nb_running_get_entry(dnode, NULL, true);
1638 isis_circuit_is_type_set(circuit, circ_type);
1639 break;
1640 }
1641
1642 return NB_OK;
1643}
1644
1645/*
1646 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1647 */
1648int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
1649 const struct lyd_node *dnode,
1650 union nb_resource *resource)
1651{
1652 bool ipv4, ipv6;
1653 struct isis_circuit *circuit;
1654
1655 if (event != NB_EV_APPLY)
1656 return NB_OK;
1657
1658 circuit = nb_running_get_entry(dnode, NULL, true);
1659 ipv4 = yang_dnode_get_bool(dnode, NULL);
1660 ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
1661 isis_circuit_af_set(circuit, ipv4, ipv6);
1662
1663 return NB_OK;
1664}
1665
1666/*
1667 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1668 */
1669int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
1670 const struct lyd_node *dnode,
1671 union nb_resource *resource)
1672{
1673 bool ipv4, ipv6;
1674 struct isis_circuit *circuit;
1675
1676 if (event != NB_EV_APPLY)
1677 return NB_OK;
1678
1679 circuit = nb_running_get_entry(dnode, NULL, true);
1680 ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
1681 ipv6 = yang_dnode_get_bool(dnode, NULL);
1682 isis_circuit_af_set(circuit, ipv4, ipv6);
1683
1684 return NB_OK;
1685}
1686
1687/*
1688 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
1689 */
1690int lib_interface_isis_bfd_monitoring_modify(enum nb_event event,
1691 const struct lyd_node *dnode,
1692 union nb_resource *resource)
1693{
1694 struct isis_circuit *circuit;
1695 bool bfd_monitoring;
1696
1697 if (event != NB_EV_APPLY)
1698 return NB_OK;
1699
1700 circuit = nb_running_get_entry(dnode, NULL, true);
1701 bfd_monitoring = yang_dnode_get_bool(dnode, NULL);
1702
1703 if (bfd_monitoring) {
1704 isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX,
1705 BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT,
1706 true);
1707 } else {
1708 isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
1709 bfd_info_free(&circuit->bfd_info);
1710 }
1711
1712 return NB_OK;
1713}
1714
1715/*
1716 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1717 */
1718int lib_interface_isis_csnp_interval_level_1_modify(
1719 enum nb_event event, const struct lyd_node *dnode,
1720 union nb_resource *resource)
1721{
1722 struct isis_circuit *circuit;
1723
1724 if (event != NB_EV_APPLY)
1725 return NB_OK;
1726
1727 circuit = nb_running_get_entry(dnode, NULL, true);
1728 circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1729
1730 return NB_OK;
1731}
1732
1733/*
1734 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1735 */
1736int lib_interface_isis_csnp_interval_level_2_modify(
1737 enum nb_event event, const struct lyd_node *dnode,
1738 union nb_resource *resource)
1739{
1740 struct isis_circuit *circuit;
1741
1742 if (event != NB_EV_APPLY)
1743 return NB_OK;
1744
1745 circuit = nb_running_get_entry(dnode, NULL, true);
1746 circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1747
1748 return NB_OK;
1749}
1750
1751/*
1752 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1753 */
1754int lib_interface_isis_psnp_interval_level_1_modify(
1755 enum nb_event event, const struct lyd_node *dnode,
1756 union nb_resource *resource)
1757{
1758 struct isis_circuit *circuit;
1759
1760 if (event != NB_EV_APPLY)
1761 return NB_OK;
1762
1763 circuit = nb_running_get_entry(dnode, NULL, true);
1764 circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1765
1766 return NB_OK;
1767}
1768
1769/*
1770 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1771 */
1772int lib_interface_isis_psnp_interval_level_2_modify(
1773 enum nb_event event, const struct lyd_node *dnode,
1774 union nb_resource *resource)
1775{
1776 struct isis_circuit *circuit;
1777
1778 if (event != NB_EV_APPLY)
1779 return NB_OK;
1780
1781 circuit = nb_running_get_entry(dnode, NULL, true);
1782 circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1783
1784 return NB_OK;
1785}
1786
1787/*
1788 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1789 */
1790int lib_interface_isis_hello_padding_modify(enum nb_event event,
1791 const struct lyd_node *dnode,
1792 union nb_resource *resource)
1793{
1794 struct isis_circuit *circuit;
1795
1796 if (event != NB_EV_APPLY)
1797 return NB_OK;
1798
1799 circuit = nb_running_get_entry(dnode, NULL, true);
1800 circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL);
1801
1802 return NB_OK;
1803}
1804
1805/*
1806 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1807 */
1808int lib_interface_isis_hello_interval_level_1_modify(
1809 enum nb_event event, const struct lyd_node *dnode,
1810 union nb_resource *resource)
1811{
1812 struct isis_circuit *circuit;
1813 uint32_t interval;
1814
1815 if (event != NB_EV_APPLY)
1816 return NB_OK;
1817
1818 circuit = nb_running_get_entry(dnode, NULL, true);
1819 interval = yang_dnode_get_uint32(dnode, NULL);
1820 circuit->hello_interval[0] = interval;
1821
1822 return NB_OK;
1823}
1824
1825/*
1826 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1827 */
1828int lib_interface_isis_hello_interval_level_2_modify(
1829 enum nb_event event, const struct lyd_node *dnode,
1830 union nb_resource *resource)
1831{
1832 struct isis_circuit *circuit;
1833 uint32_t interval;
1834
1835 if (event != NB_EV_APPLY)
1836 return NB_OK;
1837
1838 circuit = nb_running_get_entry(dnode, NULL, true);
1839 interval = yang_dnode_get_uint32(dnode, NULL);
1840 circuit->hello_interval[1] = interval;
1841
1842 return NB_OK;
1843}
1844
1845/*
1846 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
1847 */
1848int lib_interface_isis_hello_multiplier_level_1_modify(
1849 enum nb_event event, const struct lyd_node *dnode,
1850 union nb_resource *resource)
1851{
1852 struct isis_circuit *circuit;
1853 uint16_t multi;
1854
1855 if (event != NB_EV_APPLY)
1856 return NB_OK;
1857
1858 circuit = nb_running_get_entry(dnode, NULL, true);
1859 multi = yang_dnode_get_uint16(dnode, NULL);
1860 circuit->hello_multiplier[0] = multi;
1861
1862 return NB_OK;
1863}
1864
1865/*
1866 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1867 */
1868int lib_interface_isis_hello_multiplier_level_2_modify(
1869 enum nb_event event, const struct lyd_node *dnode,
1870 union nb_resource *resource)
1871{
1872 struct isis_circuit *circuit;
1873 uint16_t multi;
1874
1875 if (event != NB_EV_APPLY)
1876 return NB_OK;
1877
1878 circuit = nb_running_get_entry(dnode, NULL, true);
1879 multi = yang_dnode_get_uint16(dnode, NULL);
1880 circuit->hello_multiplier[1] = multi;
1881
1882 return NB_OK;
1883}
1884
1885/*
1886 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1887 */
1888int lib_interface_isis_metric_level_1_modify(enum nb_event event,
1889 const struct lyd_node *dnode,
1890 union nb_resource *resource)
1891{
1892 struct isis_circuit *circuit;
1893 unsigned int met;
1894
1895 if (event != NB_EV_APPLY)
1896 return NB_OK;
1897
1898 circuit = nb_running_get_entry(dnode, NULL, true);
1899 met = yang_dnode_get_uint32(dnode, NULL);
1900 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
1901
1902 return NB_OK;
1903}
1904
1905/*
1906 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1907 */
1908int lib_interface_isis_metric_level_2_modify(enum nb_event event,
1909 const struct lyd_node *dnode,
1910 union nb_resource *resource)
1911{
1912 struct isis_circuit *circuit;
1913 unsigned int met;
1914
1915 if (event != NB_EV_APPLY)
1916 return NB_OK;
1917
1918 circuit = nb_running_get_entry(dnode, NULL, true);
1919 met = yang_dnode_get_uint32(dnode, NULL);
1920 isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
1921
1922 return NB_OK;
1923}
1924
1925/*
1926 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
1927 */
1928int lib_interface_isis_priority_level_1_modify(enum nb_event event,
1929 const struct lyd_node *dnode,
1930 union nb_resource *resource)
1931{
1932 struct isis_circuit *circuit;
1933
1934 if (event != NB_EV_APPLY)
1935 return NB_OK;
1936
1937 circuit = nb_running_get_entry(dnode, NULL, true);
1938 circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
1939
1940 return NB_OK;
1941}
1942
1943/*
1944 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1945 */
1946int lib_interface_isis_priority_level_2_modify(enum nb_event event,
1947 const struct lyd_node *dnode,
1948 union nb_resource *resource)
1949{
1950 struct isis_circuit *circuit;
1951
1952 if (event != NB_EV_APPLY)
1953 return NB_OK;
1954
1955 circuit = nb_running_get_entry(dnode, NULL, true);
1956 circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
1957
1958 return NB_OK;
1959}
1960
1961/*
1962 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1963 */
1964int lib_interface_isis_network_type_modify(enum nb_event event,
1965 const struct lyd_node *dnode,
1966 union nb_resource *resource)
1967{
1968 struct isis_circuit *circuit;
1969 int net_type = yang_dnode_get_enum(dnode, NULL);
1970
1971 switch (event) {
1972 case NB_EV_VALIDATE:
1973 circuit = nb_running_get_entry(dnode, NULL, false);
1974 if (!circuit)
1975 break;
1976 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
1977 flog_warn(
1978 EC_LIB_NB_CB_CONFIG_VALIDATE,
1979 "Cannot change network type on loopback interface");
1980 return NB_ERR_VALIDATION;
1981 }
1982 if (net_type == CIRCUIT_T_BROADCAST
1983 && circuit->state == C_STATE_UP
1984 && !if_is_broadcast(circuit->interface)) {
1985 flog_warn(
1986 EC_LIB_NB_CB_CONFIG_VALIDATE,
1987 "Cannot configure non-broadcast interface for broadcast operation");
1988 return NB_ERR_VALIDATION;
1989 }
1990 break;
1991 case NB_EV_PREPARE:
1992 case NB_EV_ABORT:
1993 break;
1994 case NB_EV_APPLY:
1995 circuit = nb_running_get_entry(dnode, NULL, true);
1996 isis_circuit_circ_type_set(circuit, net_type);
1997 break;
1998 }
1999
2000 return NB_OK;
2001}
2002
2003/*
2004 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2005 */
2006int lib_interface_isis_passive_modify(enum nb_event event,
2007 const struct lyd_node *dnode,
2008 union nb_resource *resource)
2009{
2010 struct isis_circuit *circuit;
2011 struct isis_area *area;
2012 struct interface *ifp;
2013 bool passive = yang_dnode_get_bool(dnode, NULL);
2014
2015 /* validation only applies if we are setting passive to false */
2016 if (!passive && event == NB_EV_VALIDATE) {
2017 circuit = nb_running_get_entry(dnode, NULL, false);
2018 if (!circuit)
2019 return NB_OK;
2020 ifp = circuit->interface;
2021 if (!ifp)
2022 return NB_OK;
2023 if (if_is_loopback(ifp)) {
2024 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
2025 "Loopback is always passive");
2026 return NB_ERR_VALIDATION;
2027 }
2028 }
2029
2030 if (event != NB_EV_APPLY)
2031 return NB_OK;
2032
2033 circuit = nb_running_get_entry(dnode, NULL, true);
2034 if (circuit->state != C_STATE_UP) {
2035 circuit->is_passive = passive;
2036 } else {
2037 area = circuit->area;
2038 isis_csm_state_change(ISIS_DISABLE, circuit, area);
2039 circuit->is_passive = passive;
2040 isis_csm_state_change(ISIS_ENABLE, circuit, area);
2041 }
2042
2043 return NB_OK;
2044}
2045
2046/*
2047 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2048 */
2049int lib_interface_isis_password_create(enum nb_event event,
2050 const struct lyd_node *dnode,
2051 union nb_resource *resource)
2052{
2053 return NB_OK;
2054}
2055
2056int lib_interface_isis_password_destroy(enum nb_event event,
2057 const struct lyd_node *dnode)
2058{
2059 struct isis_circuit *circuit;
2060
2061 if (event != NB_EV_APPLY)
2062 return NB_OK;
2063
2064 circuit = nb_running_get_entry(dnode, NULL, true);
2065 isis_circuit_passwd_unset(circuit);
2066
2067 return NB_OK;
2068}
2069
2070/*
2071 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2072 */
2073int lib_interface_isis_password_password_modify(enum nb_event event,
2074 const struct lyd_node *dnode,
2075 union nb_resource *resource)
2076{
2077 struct isis_circuit *circuit;
2078 const char *password;
2079
2080 if (event != NB_EV_APPLY)
2081 return NB_OK;
2082
2083 password = yang_dnode_get_string(dnode, NULL);
2084 circuit = nb_running_get_entry(dnode, NULL, true);
2085
2086 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
2087
2088 return NB_OK;
2089}
2090
2091/*
2092 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2093 */
2094int lib_interface_isis_password_password_type_modify(
2095 enum nb_event event, const struct lyd_node *dnode,
2096 union nb_resource *resource)
2097{
2098 struct isis_circuit *circuit;
2099 uint8_t pass_type;
2100
2101 if (event != NB_EV_APPLY)
2102 return NB_OK;
2103
2104 pass_type = yang_dnode_get_enum(dnode, NULL);
2105 circuit = nb_running_get_entry(dnode, NULL, true);
2106 circuit->passwd.type = pass_type;
2107
2108 return NB_OK;
2109}
2110
2111/*
2112 * XPath:
2113 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2114 */
2115int lib_interface_isis_disable_three_way_handshake_modify(
2116 enum nb_event event, const struct lyd_node *dnode,
2117 union nb_resource *resource)
2118{
2119 struct isis_circuit *circuit;
2120
2121 if (event != NB_EV_APPLY)
2122 return NB_OK;
2123
2124 circuit = nb_running_get_entry(dnode, NULL, true);
2125 circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
2126
2127 return NB_OK;
2128}
2129
2130/*
2131 * XPath:
2132 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2133 */
2134static int lib_interface_isis_multi_topology_common(
2135 enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
2136{
2137 struct isis_circuit *circuit;
2138 bool value;
2139
2140 switch (event) {
2141 case NB_EV_VALIDATE:
2142 circuit = nb_running_get_entry(dnode, NULL, false);
2143 if (circuit && circuit->area && circuit->area->oldmetric) {
2144 flog_warn(
2145 EC_LIB_NB_CB_CONFIG_VALIDATE,
2146 "Multi topology IS-IS can only be used with wide metrics");
2147 return NB_ERR_VALIDATION;
2148 }
2149 break;
2150 case NB_EV_PREPARE:
2151 case NB_EV_ABORT:
2152 break;
2153 case NB_EV_APPLY:
2154 circuit = nb_running_get_entry(dnode, NULL, true);
2155 value = yang_dnode_get_bool(dnode, NULL);
2156 isis_circuit_mt_enabled_set(circuit, mtid, value);
2157 break;
2158 }
2159
2160 return NB_OK;
2161}
2162
2163int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2164 enum nb_event event, const struct lyd_node *dnode,
2165 union nb_resource *resource)
2166{
2167 return lib_interface_isis_multi_topology_common(event, dnode,
2168 ISIS_MT_IPV4_UNICAST);
2169}
2170
2171/*
2172 * XPath:
2173 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2174 */
2175int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2176 enum nb_event event, const struct lyd_node *dnode,
2177 union nb_resource *resource)
2178{
2179 return lib_interface_isis_multi_topology_common(event, dnode,
2180 ISIS_MT_IPV4_MULTICAST);
2181}
2182
2183/*
2184 * XPath:
2185 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2186 */
2187int lib_interface_isis_multi_topology_ipv4_management_modify(
2188 enum nb_event event, const struct lyd_node *dnode,
2189 union nb_resource *resource)
2190{
2191 return lib_interface_isis_multi_topology_common(event, dnode,
2192 ISIS_MT_IPV4_MGMT);
2193}
2194
2195/*
2196 * XPath:
2197 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2198 */
2199int lib_interface_isis_multi_topology_ipv6_unicast_modify(
2200 enum nb_event event, const struct lyd_node *dnode,
2201 union nb_resource *resource)
2202{
2203 return lib_interface_isis_multi_topology_common(event, dnode,
2204 ISIS_MT_IPV6_UNICAST);
2205}
2206
2207/*
2208 * XPath:
2209 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2210 */
2211int lib_interface_isis_multi_topology_ipv6_multicast_modify(
2212 enum nb_event event, const struct lyd_node *dnode,
2213 union nb_resource *resource)
2214{
2215 return lib_interface_isis_multi_topology_common(event, dnode,
2216 ISIS_MT_IPV6_MULTICAST);
2217}
2218
2219/*
2220 * XPath:
2221 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2222 */
2223int lib_interface_isis_multi_topology_ipv6_management_modify(
2224 enum nb_event event, const struct lyd_node *dnode,
2225 union nb_resource *resource)
2226{
2227 return lib_interface_isis_multi_topology_common(event, dnode,
2228 ISIS_MT_IPV6_MGMT);
2229}
2230
2231/*
2232 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2233 */
2234int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2235 enum nb_event event, const struct lyd_node *dnode,
2236 union nb_resource *resource)
2237{
2238 return lib_interface_isis_multi_topology_common(event, dnode,
2239 ISIS_MT_IPV6_DSTSRC);
2240}