]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_nb_config.c
Merge pull request #5625 from qlyoung/fix-zapi-ipset-name-nullterm
[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
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);
1560 return NB_OK;
1561 }
1562
1563 /*
1564 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1565 */
1566 int 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 */
1602 int 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 */
1648 int 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 */
1669 int 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 */
1690 int 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 */
1718 int 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 */
1736 int 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 */
1754 int 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 */
1772 int 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 */
1790 int 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 */
1808 int 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 */
1828 int 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 */
1848 int 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 */
1868 int 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 */
1888 int 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 */
1908 int 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 */
1928 int 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 */
1946 int 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 */
1964 int 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 */
2006 int 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 */
2049 int 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
2056 int 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 */
2073 int 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 */
2094 int 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 */
2115 int 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 */
2134 static 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
2163 int 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 */
2175 int 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 */
2187 int 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 */
2199 int 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 */
2211 int 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 */
2223 int 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 */
2234 int 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 }