]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_nb_config.c
Merge pull request #5192 from donaldsharp/zebra_rejection
[mirror_frr.git] / isisd / isis_nb_config.c
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 */
52 int 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
73 int 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 */
89 int 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 */
109 int 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
193 int 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 */
235 int 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 */
253 int 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 */
273 int 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 */
293 int 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 */
315 int 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 */
333 int 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 */
376 int 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 */
396 int 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 */
416 int 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 */
436 int 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 */
456 int 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 */
476 int 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 */
496 void 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
522 int 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
530 int 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 */
550 int 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 */
561 int 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 */
572 int 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 */
583 int 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 */
594 int 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 */
605 int 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 */
623 int 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 */
641 void 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
660 int 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
668 int 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 */
685 int 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 */
696 int 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 */
707 int 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 */
718 void 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
737 int 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
745 int 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 */
762 int 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 */
773 int 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 */
784 int 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 */
795 void 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
820 void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
821 {
822 default_info_origin_apply_finish(dnode, AF_INET);
823 }
824
825 void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
826 {
827 default_info_origin_apply_finish(dnode, AF_INET6);
828 }
829
830 int 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
838 int 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 */
857 int 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 */
868 int 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
876 int 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 */
886 int 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 */
897 int 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
905 int 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 */
924 int 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 */
935 int 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
943 int 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 */
953 int 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 */
964 void 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
984 void redistribute_ipv4_apply_finish(const struct lyd_node *dnode)
985 {
986 redistribute_apply_finish(dnode, AF_INET);
987 }
988
989 void redistribute_ipv6_apply_finish(const struct lyd_node *dnode)
990 {
991 redistribute_apply_finish(dnode, AF_INET6);
992 }
993
994 int 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
1002 int 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 */
1022 int 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
1030 int 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 */
1040 int 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 */
1051 int 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
1059 int 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 */
1079 int 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
1087 int 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 */
1097 int 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 */
1108 static 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
1138 static 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
1159 int 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
1166 int 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 */
1176 int 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 */
1187 int 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
1194 int 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 */
1203 int 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 */
1213 int 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
1220 int 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 */
1229 int 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 */
1240 int 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
1247 int 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 */
1257 int 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 */
1268 int 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
1275 int 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 */
1284 int 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 */
1294 int 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
1301 int 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 */
1310 int 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 */
1320 int 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 */
1339 int 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
1382 int 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 */
1424 int 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
1449 int 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 */
1474 int 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
1542 int 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;
1553 if (circuit->state == C_STATE_UP || circuit->state == C_STATE_CONF)
1554 isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
1555
1556 return NB_OK;
1557 }
1558
1559 /*
1560 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1561 */
1562 int lib_interface_isis_area_tag_modify(enum nb_event event,
1563 const struct lyd_node *dnode,
1564 union nb_resource *resource)
1565 {
1566 struct isis_circuit *circuit;
1567 struct interface *ifp;
1568 struct vrf *vrf;
1569 const char *area_tag, *ifname, *vrfname;
1570
1571 if (event == NB_EV_VALIDATE) {
1572 /* libyang doesn't like relative paths across module boundaries
1573 */
1574 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1575 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1576 vrf = vrf_lookup_by_name(vrfname);
1577 assert(vrf);
1578 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1579 if (!ifp)
1580 return NB_OK;
1581 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1582 area_tag = yang_dnode_get_string(dnode, NULL);
1583 if (circuit && circuit->area && circuit->area->area_tag
1584 && strcmp(circuit->area->area_tag, area_tag)) {
1585 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1586 "ISIS circuit is already defined on %s",
1587 circuit->area->area_tag);
1588 return NB_ERR_VALIDATION;
1589 }
1590 }
1591
1592 return NB_OK;
1593 }
1594
1595 /*
1596 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1597 */
1598 int lib_interface_isis_circuit_type_modify(enum nb_event event,
1599 const struct lyd_node *dnode,
1600 union nb_resource *resource)
1601 {
1602 int circ_type = yang_dnode_get_enum(dnode, NULL);
1603 struct isis_circuit *circuit;
1604 struct interface *ifp;
1605 struct vrf *vrf;
1606 const char *ifname, *vrfname;
1607
1608 switch (event) {
1609 case NB_EV_VALIDATE:
1610 /* libyang doesn't like relative paths across module boundaries
1611 */
1612 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1613 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1614 vrf = vrf_lookup_by_name(vrfname);
1615 assert(vrf);
1616 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1617 if (!ifp)
1618 break;
1619 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1620 if (circuit && circuit->state == C_STATE_UP
1621 && circuit->area->is_type != IS_LEVEL_1_AND_2
1622 && circuit->area->is_type != circ_type) {
1623 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1624 "Invalid circuit level for area %s",
1625 circuit->area->area_tag);
1626 return NB_ERR_VALIDATION;
1627 }
1628 break;
1629 case NB_EV_PREPARE:
1630 case NB_EV_ABORT:
1631 break;
1632 case NB_EV_APPLY:
1633 circuit = nb_running_get_entry(dnode, NULL, true);
1634 isis_circuit_is_type_set(circuit, circ_type);
1635 break;
1636 }
1637
1638 return NB_OK;
1639 }
1640
1641 /*
1642 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1643 */
1644 int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
1645 const struct lyd_node *dnode,
1646 union nb_resource *resource)
1647 {
1648 bool ipv4, ipv6;
1649 struct isis_circuit *circuit;
1650
1651 if (event != NB_EV_APPLY)
1652 return NB_OK;
1653
1654 circuit = nb_running_get_entry(dnode, NULL, true);
1655 ipv4 = yang_dnode_get_bool(dnode, NULL);
1656 ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
1657 isis_circuit_af_set(circuit, ipv4, ipv6);
1658
1659 return NB_OK;
1660 }
1661
1662 /*
1663 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1664 */
1665 int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
1666 const struct lyd_node *dnode,
1667 union nb_resource *resource)
1668 {
1669 bool ipv4, ipv6;
1670 struct isis_circuit *circuit;
1671
1672 if (event != NB_EV_APPLY)
1673 return NB_OK;
1674
1675 circuit = nb_running_get_entry(dnode, NULL, true);
1676 ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
1677 ipv6 = yang_dnode_get_bool(dnode, NULL);
1678 isis_circuit_af_set(circuit, ipv4, ipv6);
1679
1680 return NB_OK;
1681 }
1682
1683 /*
1684 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
1685 */
1686 int lib_interface_isis_bfd_monitoring_modify(enum nb_event event,
1687 const struct lyd_node *dnode,
1688 union nb_resource *resource)
1689 {
1690 struct isis_circuit *circuit;
1691 bool bfd_monitoring;
1692
1693 if (event != NB_EV_APPLY)
1694 return NB_OK;
1695
1696 circuit = nb_running_get_entry(dnode, NULL, true);
1697 bfd_monitoring = yang_dnode_get_bool(dnode, NULL);
1698
1699 if (bfd_monitoring) {
1700 isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX,
1701 BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT,
1702 true);
1703 } else {
1704 isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
1705 bfd_info_free(&circuit->bfd_info);
1706 }
1707
1708 return NB_OK;
1709 }
1710
1711 /*
1712 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1713 */
1714 int lib_interface_isis_csnp_interval_level_1_modify(
1715 enum nb_event event, const struct lyd_node *dnode,
1716 union nb_resource *resource)
1717 {
1718 struct isis_circuit *circuit;
1719
1720 if (event != NB_EV_APPLY)
1721 return NB_OK;
1722
1723 circuit = nb_running_get_entry(dnode, NULL, true);
1724 circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1725
1726 return NB_OK;
1727 }
1728
1729 /*
1730 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1731 */
1732 int lib_interface_isis_csnp_interval_level_2_modify(
1733 enum nb_event event, const struct lyd_node *dnode,
1734 union nb_resource *resource)
1735 {
1736 struct isis_circuit *circuit;
1737
1738 if (event != NB_EV_APPLY)
1739 return NB_OK;
1740
1741 circuit = nb_running_get_entry(dnode, NULL, true);
1742 circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1743
1744 return NB_OK;
1745 }
1746
1747 /*
1748 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1749 */
1750 int lib_interface_isis_psnp_interval_level_1_modify(
1751 enum nb_event event, const struct lyd_node *dnode,
1752 union nb_resource *resource)
1753 {
1754 struct isis_circuit *circuit;
1755
1756 if (event != NB_EV_APPLY)
1757 return NB_OK;
1758
1759 circuit = nb_running_get_entry(dnode, NULL, true);
1760 circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1761
1762 return NB_OK;
1763 }
1764
1765 /*
1766 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1767 */
1768 int lib_interface_isis_psnp_interval_level_2_modify(
1769 enum nb_event event, const struct lyd_node *dnode,
1770 union nb_resource *resource)
1771 {
1772 struct isis_circuit *circuit;
1773
1774 if (event != NB_EV_APPLY)
1775 return NB_OK;
1776
1777 circuit = nb_running_get_entry(dnode, NULL, true);
1778 circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1779
1780 return NB_OK;
1781 }
1782
1783 /*
1784 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1785 */
1786 int lib_interface_isis_hello_padding_modify(enum nb_event event,
1787 const struct lyd_node *dnode,
1788 union nb_resource *resource)
1789 {
1790 struct isis_circuit *circuit;
1791
1792 if (event != NB_EV_APPLY)
1793 return NB_OK;
1794
1795 circuit = nb_running_get_entry(dnode, NULL, true);
1796 circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL);
1797
1798 return NB_OK;
1799 }
1800
1801 /*
1802 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1803 */
1804 int lib_interface_isis_hello_interval_level_1_modify(
1805 enum nb_event event, const struct lyd_node *dnode,
1806 union nb_resource *resource)
1807 {
1808 struct isis_circuit *circuit;
1809 uint32_t interval;
1810
1811 if (event != NB_EV_APPLY)
1812 return NB_OK;
1813
1814 circuit = nb_running_get_entry(dnode, NULL, true);
1815 interval = yang_dnode_get_uint32(dnode, NULL);
1816 circuit->hello_interval[0] = interval;
1817
1818 return NB_OK;
1819 }
1820
1821 /*
1822 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1823 */
1824 int lib_interface_isis_hello_interval_level_2_modify(
1825 enum nb_event event, const struct lyd_node *dnode,
1826 union nb_resource *resource)
1827 {
1828 struct isis_circuit *circuit;
1829 uint32_t interval;
1830
1831 if (event != NB_EV_APPLY)
1832 return NB_OK;
1833
1834 circuit = nb_running_get_entry(dnode, NULL, true);
1835 interval = yang_dnode_get_uint32(dnode, NULL);
1836 circuit->hello_interval[1] = interval;
1837
1838 return NB_OK;
1839 }
1840
1841 /*
1842 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
1843 */
1844 int lib_interface_isis_hello_multiplier_level_1_modify(
1845 enum nb_event event, const struct lyd_node *dnode,
1846 union nb_resource *resource)
1847 {
1848 struct isis_circuit *circuit;
1849 uint16_t multi;
1850
1851 if (event != NB_EV_APPLY)
1852 return NB_OK;
1853
1854 circuit = nb_running_get_entry(dnode, NULL, true);
1855 multi = yang_dnode_get_uint16(dnode, NULL);
1856 circuit->hello_multiplier[0] = multi;
1857
1858 return NB_OK;
1859 }
1860
1861 /*
1862 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1863 */
1864 int lib_interface_isis_hello_multiplier_level_2_modify(
1865 enum nb_event event, const struct lyd_node *dnode,
1866 union nb_resource *resource)
1867 {
1868 struct isis_circuit *circuit;
1869 uint16_t multi;
1870
1871 if (event != NB_EV_APPLY)
1872 return NB_OK;
1873
1874 circuit = nb_running_get_entry(dnode, NULL, true);
1875 multi = yang_dnode_get_uint16(dnode, NULL);
1876 circuit->hello_multiplier[1] = multi;
1877
1878 return NB_OK;
1879 }
1880
1881 /*
1882 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1883 */
1884 int lib_interface_isis_metric_level_1_modify(enum nb_event event,
1885 const struct lyd_node *dnode,
1886 union nb_resource *resource)
1887 {
1888 struct isis_circuit *circuit;
1889 unsigned int met;
1890
1891 if (event != NB_EV_APPLY)
1892 return NB_OK;
1893
1894 circuit = nb_running_get_entry(dnode, NULL, true);
1895 met = yang_dnode_get_uint32(dnode, NULL);
1896 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
1897
1898 return NB_OK;
1899 }
1900
1901 /*
1902 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1903 */
1904 int lib_interface_isis_metric_level_2_modify(enum nb_event event,
1905 const struct lyd_node *dnode,
1906 union nb_resource *resource)
1907 {
1908 struct isis_circuit *circuit;
1909 unsigned int met;
1910
1911 if (event != NB_EV_APPLY)
1912 return NB_OK;
1913
1914 circuit = nb_running_get_entry(dnode, NULL, true);
1915 met = yang_dnode_get_uint32(dnode, NULL);
1916 isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
1917
1918 return NB_OK;
1919 }
1920
1921 /*
1922 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
1923 */
1924 int lib_interface_isis_priority_level_1_modify(enum nb_event event,
1925 const struct lyd_node *dnode,
1926 union nb_resource *resource)
1927 {
1928 struct isis_circuit *circuit;
1929
1930 if (event != NB_EV_APPLY)
1931 return NB_OK;
1932
1933 circuit = nb_running_get_entry(dnode, NULL, true);
1934 circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
1935
1936 return NB_OK;
1937 }
1938
1939 /*
1940 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1941 */
1942 int lib_interface_isis_priority_level_2_modify(enum nb_event event,
1943 const struct lyd_node *dnode,
1944 union nb_resource *resource)
1945 {
1946 struct isis_circuit *circuit;
1947
1948 if (event != NB_EV_APPLY)
1949 return NB_OK;
1950
1951 circuit = nb_running_get_entry(dnode, NULL, true);
1952 circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
1953
1954 return NB_OK;
1955 }
1956
1957 /*
1958 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1959 */
1960 int lib_interface_isis_network_type_modify(enum nb_event event,
1961 const struct lyd_node *dnode,
1962 union nb_resource *resource)
1963 {
1964 struct isis_circuit *circuit;
1965 int net_type = yang_dnode_get_enum(dnode, NULL);
1966
1967 switch (event) {
1968 case NB_EV_VALIDATE:
1969 circuit = nb_running_get_entry(dnode, NULL, false);
1970 if (!circuit)
1971 break;
1972 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
1973 flog_warn(
1974 EC_LIB_NB_CB_CONFIG_VALIDATE,
1975 "Cannot change network type on loopback interface");
1976 return NB_ERR_VALIDATION;
1977 }
1978 if (net_type == CIRCUIT_T_BROADCAST
1979 && circuit->state == C_STATE_UP
1980 && !if_is_broadcast(circuit->interface)) {
1981 flog_warn(
1982 EC_LIB_NB_CB_CONFIG_VALIDATE,
1983 "Cannot configure non-broadcast interface for broadcast operation");
1984 return NB_ERR_VALIDATION;
1985 }
1986 break;
1987 case NB_EV_PREPARE:
1988 case NB_EV_ABORT:
1989 break;
1990 case NB_EV_APPLY:
1991 circuit = nb_running_get_entry(dnode, NULL, true);
1992 isis_circuit_circ_type_set(circuit, net_type);
1993 break;
1994 }
1995
1996 return NB_OK;
1997 }
1998
1999 /*
2000 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2001 */
2002 int lib_interface_isis_passive_modify(enum nb_event event,
2003 const struct lyd_node *dnode,
2004 union nb_resource *resource)
2005 {
2006 struct isis_circuit *circuit;
2007 struct isis_area *area;
2008 struct interface *ifp;
2009 bool passive = yang_dnode_get_bool(dnode, NULL);
2010
2011 /* validation only applies if we are setting passive to false */
2012 if (!passive && event == NB_EV_VALIDATE) {
2013 circuit = nb_running_get_entry(dnode, NULL, false);
2014 if (!circuit)
2015 return NB_OK;
2016 ifp = circuit->interface;
2017 if (!ifp)
2018 return NB_OK;
2019 if (if_is_loopback(ifp)) {
2020 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
2021 "Loopback is always passive");
2022 return NB_ERR_VALIDATION;
2023 }
2024 }
2025
2026 if (event != NB_EV_APPLY)
2027 return NB_OK;
2028
2029 circuit = nb_running_get_entry(dnode, NULL, true);
2030 if (circuit->state != C_STATE_UP) {
2031 circuit->is_passive = passive;
2032 } else {
2033 area = circuit->area;
2034 isis_csm_state_change(ISIS_DISABLE, circuit, area);
2035 circuit->is_passive = passive;
2036 isis_csm_state_change(ISIS_ENABLE, circuit, area);
2037 }
2038
2039 return NB_OK;
2040 }
2041
2042 /*
2043 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2044 */
2045 int lib_interface_isis_password_create(enum nb_event event,
2046 const struct lyd_node *dnode,
2047 union nb_resource *resource)
2048 {
2049 return NB_OK;
2050 }
2051
2052 int lib_interface_isis_password_destroy(enum nb_event event,
2053 const struct lyd_node *dnode)
2054 {
2055 struct isis_circuit *circuit;
2056
2057 if (event != NB_EV_APPLY)
2058 return NB_OK;
2059
2060 circuit = nb_running_get_entry(dnode, NULL, true);
2061 isis_circuit_passwd_unset(circuit);
2062
2063 return NB_OK;
2064 }
2065
2066 /*
2067 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2068 */
2069 int lib_interface_isis_password_password_modify(enum nb_event event,
2070 const struct lyd_node *dnode,
2071 union nb_resource *resource)
2072 {
2073 struct isis_circuit *circuit;
2074 const char *password;
2075
2076 if (event != NB_EV_APPLY)
2077 return NB_OK;
2078
2079 password = yang_dnode_get_string(dnode, NULL);
2080 circuit = nb_running_get_entry(dnode, NULL, true);
2081
2082 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
2083
2084 return NB_OK;
2085 }
2086
2087 /*
2088 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2089 */
2090 int lib_interface_isis_password_password_type_modify(
2091 enum nb_event event, const struct lyd_node *dnode,
2092 union nb_resource *resource)
2093 {
2094 struct isis_circuit *circuit;
2095 uint8_t pass_type;
2096
2097 if (event != NB_EV_APPLY)
2098 return NB_OK;
2099
2100 pass_type = yang_dnode_get_enum(dnode, NULL);
2101 circuit = nb_running_get_entry(dnode, NULL, true);
2102 circuit->passwd.type = pass_type;
2103
2104 return NB_OK;
2105 }
2106
2107 /*
2108 * XPath:
2109 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2110 */
2111 int lib_interface_isis_disable_three_way_handshake_modify(
2112 enum nb_event event, const struct lyd_node *dnode,
2113 union nb_resource *resource)
2114 {
2115 struct isis_circuit *circuit;
2116
2117 if (event != NB_EV_APPLY)
2118 return NB_OK;
2119
2120 circuit = nb_running_get_entry(dnode, NULL, true);
2121 circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
2122
2123 return NB_OK;
2124 }
2125
2126 /*
2127 * XPath:
2128 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2129 */
2130 static int lib_interface_isis_multi_topology_common(
2131 enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
2132 {
2133 struct isis_circuit *circuit;
2134 bool value;
2135
2136 switch (event) {
2137 case NB_EV_VALIDATE:
2138 circuit = nb_running_get_entry(dnode, NULL, false);
2139 if (circuit && circuit->area && circuit->area->oldmetric) {
2140 flog_warn(
2141 EC_LIB_NB_CB_CONFIG_VALIDATE,
2142 "Multi topology IS-IS can only be used with wide metrics");
2143 return NB_ERR_VALIDATION;
2144 }
2145 break;
2146 case NB_EV_PREPARE:
2147 case NB_EV_ABORT:
2148 break;
2149 case NB_EV_APPLY:
2150 circuit = nb_running_get_entry(dnode, NULL, true);
2151 value = yang_dnode_get_bool(dnode, NULL);
2152 isis_circuit_mt_enabled_set(circuit, mtid, value);
2153 break;
2154 }
2155
2156 return NB_OK;
2157 }
2158
2159 int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2160 enum nb_event event, const struct lyd_node *dnode,
2161 union nb_resource *resource)
2162 {
2163 return lib_interface_isis_multi_topology_common(event, dnode,
2164 ISIS_MT_IPV4_UNICAST);
2165 }
2166
2167 /*
2168 * XPath:
2169 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2170 */
2171 int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2172 enum nb_event event, const struct lyd_node *dnode,
2173 union nb_resource *resource)
2174 {
2175 return lib_interface_isis_multi_topology_common(event, dnode,
2176 ISIS_MT_IPV4_MULTICAST);
2177 }
2178
2179 /*
2180 * XPath:
2181 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2182 */
2183 int lib_interface_isis_multi_topology_ipv4_management_modify(
2184 enum nb_event event, const struct lyd_node *dnode,
2185 union nb_resource *resource)
2186 {
2187 return lib_interface_isis_multi_topology_common(event, dnode,
2188 ISIS_MT_IPV4_MGMT);
2189 }
2190
2191 /*
2192 * XPath:
2193 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2194 */
2195 int lib_interface_isis_multi_topology_ipv6_unicast_modify(
2196 enum nb_event event, const struct lyd_node *dnode,
2197 union nb_resource *resource)
2198 {
2199 return lib_interface_isis_multi_topology_common(event, dnode,
2200 ISIS_MT_IPV6_UNICAST);
2201 }
2202
2203 /*
2204 * XPath:
2205 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2206 */
2207 int lib_interface_isis_multi_topology_ipv6_multicast_modify(
2208 enum nb_event event, const struct lyd_node *dnode,
2209 union nb_resource *resource)
2210 {
2211 return lib_interface_isis_multi_topology_common(event, dnode,
2212 ISIS_MT_IPV6_MULTICAST);
2213 }
2214
2215 /*
2216 * XPath:
2217 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2218 */
2219 int lib_interface_isis_multi_topology_ipv6_management_modify(
2220 enum nb_event event, const struct lyd_node *dnode,
2221 union nb_resource *resource)
2222 {
2223 return lib_interface_isis_multi_topology_common(event, dnode,
2224 ISIS_MT_IPV6_MGMT);
2225 }
2226
2227 /*
2228 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2229 */
2230 int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2231 enum nb_event event, const struct lyd_node *dnode,
2232 union nb_resource *resource)
2233 {
2234 return lib_interface_isis_multi_topology_common(event, dnode,
2235 ISIS_MT_IPV6_DSTSRC);
2236 }