]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_northbound.c
doc: Add documentation for `bgp ebgp-requires-policy` command
[mirror_frr.git] / isisd / isis_northbound.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 #include "northbound.h"
25 #include "libfrr.h"
26 #include "linklist.h"
27 #include "log.h"
28 #include "isisd/isis_constants.h"
29 #include "isisd/isis_common.h"
30 #include "isisd/isis_flags.h"
31 #include "isisd/isis_circuit.h"
32 #include "isisd/isisd.h"
33 #include "isisd/isis_lsp.h"
34 #include "isisd/isis_pdu.h"
35 #include "isisd/isis_dynhn.h"
36 #include "isisd/isis_misc.h"
37 #include "isisd/isis_csm.h"
38 #include "isisd/isis_adjacency.h"
39 #include "isisd/isis_spf.h"
40 #include "isisd/isis_te.h"
41 #include "isisd/isis_memory.h"
42 #include "isisd/isis_mt.h"
43 #include "isisd/isis_cli.h"
44 #include "isisd/isis_redist.h"
45 #include "lib/spf_backoff.h"
46 #include "lib/lib_errors.h"
47 #include "lib/vrf.h"
48
49 /*
50 * XPath: /frr-isisd:isis/instance
51 */
52 static int isis_instance_create(enum nb_event event,
53 const struct lyd_node *dnode,
54 union nb_resource *resource)
55 {
56 struct isis_area *area;
57 const char *area_tag;
58
59 if (event != NB_EV_APPLY)
60 return NB_OK;
61
62 area_tag = yang_dnode_get_string(dnode, "./area-tag");
63 area = isis_area_lookup(area_tag);
64 if (area)
65 return NB_ERR_INCONSISTENCY;
66
67 area = isis_area_create(area_tag);
68 /* save area in dnode to avoid looking it up all the time */
69 nb_running_set_entry(dnode, area);
70
71 return NB_OK;
72 }
73
74 static int isis_instance_destroy(enum nb_event event,
75 const struct lyd_node *dnode)
76 {
77 struct isis_area *area;
78
79 if (event != NB_EV_APPLY)
80 return NB_OK;
81
82 area = nb_running_unset_entry(dnode);
83 isis_area_destroy(area->area_tag);
84
85 return NB_OK;
86 }
87
88 /*
89 * XPath: /frr-isisd:isis/instance/is-type
90 */
91 static int isis_instance_is_type_modify(enum nb_event event,
92 const struct lyd_node *dnode,
93 union nb_resource *resource)
94 {
95 struct isis_area *area;
96 int type;
97
98 if (event != NB_EV_APPLY)
99 return NB_OK;
100
101 area = nb_running_get_entry(dnode, NULL, true);
102 type = yang_dnode_get_enum(dnode, NULL);
103 isis_area_is_type_set(area, type);
104
105 return NB_OK;
106 }
107
108 /*
109 * XPath: /frr-isisd:isis/instance/area-address
110 */
111 static int isis_instance_area_address_create(enum nb_event event,
112 const struct lyd_node *dnode,
113 union nb_resource *resource)
114 {
115 struct isis_area *area;
116 struct area_addr addr, *addrr = NULL, *addrp = NULL;
117 struct listnode *node;
118 uint8_t buff[255];
119 const char *net_title = yang_dnode_get_string(dnode, NULL);
120
121 switch (event) {
122 case NB_EV_VALIDATE:
123 addr.addr_len = dotformat2buff(buff, net_title);
124 memcpy(addr.area_addr, buff, addr.addr_len);
125 if (addr.area_addr[addr.addr_len - 1] != 0) {
126 flog_warn(
127 EC_LIB_NB_CB_CONFIG_VALIDATE,
128 "nsel byte (last byte) in area address must be 0");
129 return NB_ERR_VALIDATION;
130 }
131 if (isis->sysid_set) {
132 /* Check that the SystemID portions match */
133 if (memcmp(isis->sysid, GETSYSID((&addr)),
134 ISIS_SYS_ID_LEN)) {
135 flog_warn(
136 EC_LIB_NB_CB_CONFIG_VALIDATE,
137 "System ID must not change when defining additional area addresses");
138 return NB_ERR_VALIDATION;
139 }
140 }
141 break;
142 case NB_EV_PREPARE:
143 addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
144 addrr->addr_len = dotformat2buff(buff, net_title);
145 memcpy(addrr->area_addr, buff, addrr->addr_len);
146 resource->ptr = addrr;
147 break;
148 case NB_EV_ABORT:
149 XFREE(MTYPE_ISIS_AREA_ADDR, resource->ptr);
150 break;
151 case NB_EV_APPLY:
152 area = nb_running_get_entry(dnode, NULL, true);
153 addrr = resource->ptr;
154
155 if (isis->sysid_set == 0) {
156 /*
157 * First area address - get the SystemID for this router
158 */
159 memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
160 isis->sysid_set = 1;
161 } else {
162 /* check that we don't already have this address */
163 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
164 addrp)) {
165 if ((addrp->addr_len + ISIS_SYS_ID_LEN
166 + ISIS_NSEL_LEN)
167 != (addrr->addr_len))
168 continue;
169 if (!memcmp(addrp->area_addr, addrr->area_addr,
170 addrr->addr_len)) {
171 XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
172 return NB_OK; /* silent fail */
173 }
174 }
175 }
176
177 /*Forget the systemID part of the address */
178 addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
179 assert(area->area_addrs); /* to silence scan-build sillyness */
180 listnode_add(area->area_addrs, addrr);
181
182 /* only now we can safely generate our LSPs for this area */
183 if (listcount(area->area_addrs) > 0) {
184 if (area->is_type & IS_LEVEL_1)
185 lsp_generate(area, IS_LEVEL_1);
186 if (area->is_type & IS_LEVEL_2)
187 lsp_generate(area, IS_LEVEL_2);
188 }
189 break;
190 }
191
192 return NB_OK;
193 }
194
195 static int isis_instance_area_address_destroy(enum nb_event event,
196 const struct lyd_node *dnode)
197 {
198 struct area_addr addr, *addrp = NULL;
199 struct listnode *node;
200 uint8_t buff[255];
201 struct isis_area *area;
202 const char *net_title;
203
204 if (event != NB_EV_APPLY)
205 return NB_OK;
206
207 net_title = yang_dnode_get_string(dnode, NULL);
208 addr.addr_len = dotformat2buff(buff, net_title);
209 memcpy(addr.area_addr, buff, (int)addr.addr_len);
210 area = nb_running_get_entry(dnode, NULL, true);
211 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
212 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
213 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
214 break;
215 }
216 if (!addrp)
217 return NB_ERR_INCONSISTENCY;
218
219 listnode_delete(area->area_addrs, addrp);
220 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
221 /*
222 * Last area address - reset the SystemID for this router
223 */
224 if (listcount(area->area_addrs) == 0) {
225 memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
226 isis->sysid_set = 0;
227 if (isis->debugs & DEBUG_EVENTS)
228 zlog_debug("Router has no SystemID");
229 }
230
231 return NB_OK;
232 }
233
234 /*
235 * XPath: /frr-isisd:isis/instance/dynamic-hostname
236 */
237 static int isis_instance_dynamic_hostname_modify(enum nb_event event,
238 const struct lyd_node *dnode,
239 union nb_resource *resource)
240 {
241 struct isis_area *area;
242
243 if (event != NB_EV_APPLY)
244 return NB_OK;
245
246 area = nb_running_get_entry(dnode, NULL, true);
247 isis_area_dynhostname_set(area, yang_dnode_get_bool(dnode, NULL));
248
249 return NB_OK;
250 }
251
252 /*
253 * XPath: /frr-isisd:isis/instance/attached
254 */
255 static int isis_instance_attached_modify(enum nb_event event,
256 const struct lyd_node *dnode,
257 union nb_resource *resource)
258 {
259 struct isis_area *area;
260 bool attached;
261
262 if (event != NB_EV_APPLY)
263 return NB_OK;
264
265 area = nb_running_get_entry(dnode, NULL, true);
266 attached = yang_dnode_get_bool(dnode, NULL);
267 isis_area_attached_bit_set(area, attached);
268
269 return NB_OK;
270 }
271
272 /*
273 * XPath: /frr-isisd:isis/instance/overload
274 */
275 static int isis_instance_overload_modify(enum nb_event event,
276 const struct lyd_node *dnode,
277 union nb_resource *resource)
278 {
279 struct isis_area *area;
280 bool overload;
281
282 if (event != NB_EV_APPLY)
283 return NB_OK;
284
285 area = nb_running_get_entry(dnode, NULL, true);
286 overload = yang_dnode_get_bool(dnode, NULL);
287 isis_area_overload_bit_set(area, overload);
288
289 return NB_OK;
290 }
291
292 /*
293 * XPath: /frr-isisd:isis/instance/metric-style
294 */
295 static int isis_instance_metric_style_modify(enum nb_event event,
296 const struct lyd_node *dnode,
297 union nb_resource *resource)
298 {
299 struct isis_area *area;
300 bool old_metric, new_metric;
301 enum isis_metric_style metric_style = yang_dnode_get_enum(dnode, NULL);
302
303 if (event != NB_EV_APPLY)
304 return NB_OK;
305
306 area = nb_running_get_entry(dnode, NULL, true);
307 old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true;
308 new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true;
309 isis_area_metricstyle_set(area, old_metric, new_metric);
310
311 return NB_OK;
312 }
313
314 /*
315 * XPath: /frr-isisd:isis/instance/purge-originator
316 */
317 static int isis_instance_purge_originator_modify(enum nb_event event,
318 const struct lyd_node *dnode,
319 union nb_resource *resource)
320 {
321 struct isis_area *area;
322
323 if (event != NB_EV_APPLY)
324 return NB_OK;
325
326 area = nb_running_get_entry(dnode, NULL, true);
327 area->purge_originator = yang_dnode_get_bool(dnode, NULL);
328
329 return NB_OK;
330 }
331
332 /*
333 * XPath: /frr-isisd:isis/instance/lsp/mtu
334 */
335 static int isis_instance_lsp_mtu_modify(enum nb_event event,
336 const struct lyd_node *dnode,
337 union nb_resource *resource)
338 {
339 struct listnode *node;
340 struct isis_circuit *circuit;
341 uint16_t lsp_mtu = yang_dnode_get_uint16(dnode, NULL);
342 struct isis_area *area;
343
344 switch (event) {
345 case NB_EV_VALIDATE:
346 area = nb_running_get_entry(dnode, NULL, false);
347 if (!area)
348 break;
349 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
350 if (circuit->state != C_STATE_INIT
351 && circuit->state != C_STATE_UP)
352 continue;
353 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
354 flog_warn(
355 EC_LIB_NB_CB_CONFIG_VALIDATE,
356 "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
357 circuit->interface->name,
358 isis_circuit_pdu_size(circuit));
359 return NB_ERR_VALIDATION;
360 }
361 }
362 break;
363 case NB_EV_PREPARE:
364 case NB_EV_ABORT:
365 break;
366 case NB_EV_APPLY:
367 area = nb_running_get_entry(dnode, NULL, true);
368 isis_area_lsp_mtu_set(area, lsp_mtu);
369 break;
370 }
371
372 return NB_OK;
373 }
374
375 /*
376 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-1
377 */
378 static int
379 isis_instance_lsp_refresh_interval_level_1_modify(enum nb_event event,
380 const struct lyd_node *dnode,
381 union nb_resource *resource)
382 {
383 struct isis_area *area;
384 uint16_t refr_int;
385
386 if (event != NB_EV_APPLY)
387 return NB_OK;
388
389 refr_int = yang_dnode_get_uint16(dnode, NULL);
390 area = nb_running_get_entry(dnode, NULL, true);
391 isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int);
392
393 return NB_OK;
394 }
395
396 /*
397 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-2
398 */
399 static int
400 isis_instance_lsp_refresh_interval_level_2_modify(enum nb_event event,
401 const struct lyd_node *dnode,
402 union nb_resource *resource)
403 {
404 struct isis_area *area;
405 uint16_t refr_int;
406
407 if (event != NB_EV_APPLY)
408 return NB_OK;
409
410 refr_int = yang_dnode_get_uint16(dnode, NULL);
411 area = nb_running_get_entry(dnode, NULL, true);
412 isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int);
413
414 return NB_OK;
415 }
416
417 /*
418 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-1
419 */
420 static int
421 isis_instance_lsp_maximum_lifetime_level_1_modify(enum nb_event event,
422 const struct lyd_node *dnode,
423 union nb_resource *resource)
424 {
425 struct isis_area *area;
426 uint16_t max_lt;
427
428 if (event != NB_EV_APPLY)
429 return NB_OK;
430
431 max_lt = yang_dnode_get_uint16(dnode, NULL);
432 area = nb_running_get_entry(dnode, NULL, true);
433 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt);
434
435 return NB_OK;
436 }
437
438 /*
439 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-2
440 */
441 static int
442 isis_instance_lsp_maximum_lifetime_level_2_modify(enum nb_event event,
443 const struct lyd_node *dnode,
444 union nb_resource *resource)
445 {
446 struct isis_area *area;
447 uint16_t max_lt;
448
449 if (event != NB_EV_APPLY)
450 return NB_OK;
451
452 max_lt = yang_dnode_get_uint16(dnode, NULL);
453 area = nb_running_get_entry(dnode, NULL, true);
454 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt);
455
456 return NB_OK;
457 }
458
459 /*
460 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-1
461 */
462 static int isis_instance_lsp_generation_interval_level_1_modify(
463 enum nb_event event, const struct lyd_node *dnode,
464 union nb_resource *resource)
465 {
466 struct isis_area *area;
467 uint16_t gen_int;
468
469 if (event != NB_EV_APPLY)
470 return NB_OK;
471
472 gen_int = yang_dnode_get_uint16(dnode, NULL);
473 area = nb_running_get_entry(dnode, NULL, true);
474 area->lsp_gen_interval[0] = gen_int;
475
476 return NB_OK;
477 }
478
479 /*
480 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-2
481 */
482 static int isis_instance_lsp_generation_interval_level_2_modify(
483 enum nb_event event, const struct lyd_node *dnode,
484 union nb_resource *resource)
485 {
486 struct isis_area *area;
487 uint16_t gen_int;
488
489 if (event != NB_EV_APPLY)
490 return NB_OK;
491
492 gen_int = yang_dnode_get_uint16(dnode, NULL);
493 area = nb_running_get_entry(dnode, NULL, true);
494 area->lsp_gen_interval[1] = gen_int;
495
496 return NB_OK;
497 }
498
499 /*
500 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
501 */
502 static void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode)
503 {
504 long init_delay = yang_dnode_get_uint16(dnode, "./init-delay");
505 long short_delay = yang_dnode_get_uint16(dnode, "./short-delay");
506 long long_delay = yang_dnode_get_uint16(dnode, "./long-delay");
507 long holddown = yang_dnode_get_uint16(dnode, "./hold-down");
508 long timetolearn = yang_dnode_get_uint16(dnode, "./time-to-learn");
509 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
510 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
511 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
512
513 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
514 spf_backoff_free(area->spf_delay_ietf[0]);
515 area->spf_delay_ietf[0] =
516 spf_backoff_new(master, buf, init_delay, short_delay,
517 long_delay, holddown, timetolearn);
518
519 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
520 spf_backoff_free(area->spf_delay_ietf[1]);
521 area->spf_delay_ietf[1] =
522 spf_backoff_new(master, buf, init_delay, short_delay,
523 long_delay, holddown, timetolearn);
524
525 XFREE(MTYPE_TMP, buf);
526 }
527
528 static int
529 isis_instance_spf_ietf_backoff_delay_create(enum nb_event event,
530 const struct lyd_node *dnode,
531 union nb_resource *resource)
532 {
533 /* All the work is done in the apply_finish */
534 return NB_OK;
535 }
536
537 static int
538 isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event,
539 const struct lyd_node *dnode)
540 {
541 struct isis_area *area;
542
543 if (event != NB_EV_APPLY)
544 return NB_OK;
545
546 area = nb_running_get_entry(dnode, NULL, true);
547 spf_backoff_free(area->spf_delay_ietf[0]);
548 spf_backoff_free(area->spf_delay_ietf[1]);
549 area->spf_delay_ietf[0] = NULL;
550 area->spf_delay_ietf[1] = NULL;
551
552 return NB_OK;
553 }
554
555 /*
556 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
557 */
558 static int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
559 enum nb_event event, const struct lyd_node *dnode,
560 union nb_resource *resource)
561 {
562 /* All the work is done in the apply_finish */
563 return NB_OK;
564 }
565
566 /*
567 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
568 */
569 static int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
570 enum nb_event event, const struct lyd_node *dnode,
571 union nb_resource *resource)
572 {
573 /* All the work is done in the apply_finish */
574 return NB_OK;
575 }
576
577 /*
578 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
579 */
580 static int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
581 enum nb_event event, const struct lyd_node *dnode,
582 union nb_resource *resource)
583 {
584 /* All the work is done in the apply_finish */
585 return NB_OK;
586 }
587
588 /*
589 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
590 */
591 static int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
592 enum nb_event event, const struct lyd_node *dnode,
593 union nb_resource *resource)
594 {
595 /* All the work is done in the apply_finish */
596 return NB_OK;
597 }
598
599 /*
600 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
601 */
602 static int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
603 enum nb_event event, const struct lyd_node *dnode,
604 union nb_resource *resource)
605 {
606 /* All the work is done in the apply_finish */
607 return NB_OK;
608 }
609
610 /*
611 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
612 */
613 static int
614 isis_instance_spf_minimum_interval_level_1_modify(enum nb_event event,
615 const struct lyd_node *dnode,
616 union nb_resource *resource)
617 {
618 struct isis_area *area;
619
620 if (event != NB_EV_APPLY)
621 return NB_OK;
622
623 area = nb_running_get_entry(dnode, NULL, true);
624 area->min_spf_interval[0] = yang_dnode_get_uint16(dnode, NULL);
625
626 return NB_OK;
627 }
628
629 /*
630 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
631 */
632 static int
633 isis_instance_spf_minimum_interval_level_2_modify(enum nb_event event,
634 const struct lyd_node *dnode,
635 union nb_resource *resource)
636 {
637 struct isis_area *area;
638
639 if (event != NB_EV_APPLY)
640 return NB_OK;
641
642 area = nb_running_get_entry(dnode, NULL, true);
643 area->min_spf_interval[1] = yang_dnode_get_uint16(dnode, NULL);
644
645 return NB_OK;
646 }
647
648 /*
649 * XPath: /frr-isisd:isis/instance/area-password
650 */
651 static void area_password_apply_finish(const struct lyd_node *dnode)
652 {
653 const char *password = yang_dnode_get_string(dnode, "./password");
654 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
655 int pass_type = yang_dnode_get_enum(dnode, "./password-type");
656 uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
657
658 switch (pass_type) {
659 case ISIS_PASSWD_TYPE_CLEARTXT:
660 isis_area_passwd_cleartext_set(area, IS_LEVEL_1, password,
661 snp_auth);
662 break;
663 case ISIS_PASSWD_TYPE_HMAC_MD5:
664 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_1, password,
665 snp_auth);
666 break;
667 }
668 }
669
670 static int isis_instance_area_password_create(enum nb_event event,
671 const struct lyd_node *dnode,
672 union nb_resource *resource)
673 {
674 /* actual setting is done in apply_finish */
675 return NB_OK;
676 }
677
678 static int isis_instance_area_password_destroy(enum nb_event event,
679 const struct lyd_node *dnode)
680 {
681 struct isis_area *area;
682
683 if (event != NB_EV_APPLY)
684 return NB_OK;
685
686 area = nb_running_get_entry(dnode, NULL, true);
687 isis_area_passwd_unset(area, IS_LEVEL_1);
688
689 return NB_OK;
690 }
691
692 /*
693 * XPath: /frr-isisd:isis/instance/area-password/password
694 */
695 static int
696 isis_instance_area_password_password_modify(enum nb_event event,
697 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/password-type
706 */
707 static int
708 isis_instance_area_password_password_type_modify(enum nb_event event,
709 const struct lyd_node *dnode,
710 union nb_resource *resource)
711 {
712 /* actual setting is done in apply_finish */
713 return NB_OK;
714 }
715
716 /*
717 * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
718 */
719 static int isis_instance_area_password_authenticate_snp_modify(
720 enum nb_event event, const struct lyd_node *dnode,
721 union nb_resource *resource)
722 {
723 /* actual setting is done in apply_finish */
724 return NB_OK;
725 }
726
727 /*
728 * XPath: /frr-isisd:isis/instance/domain-password
729 */
730 static void domain_password_apply_finish(const struct lyd_node *dnode)
731 {
732 const char *password = yang_dnode_get_string(dnode, "./password");
733 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
734 int pass_type = yang_dnode_get_enum(dnode, "./password-type");
735 uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
736
737 switch (pass_type) {
738 case ISIS_PASSWD_TYPE_CLEARTXT:
739 isis_area_passwd_cleartext_set(area, IS_LEVEL_2, password,
740 snp_auth);
741 break;
742 case ISIS_PASSWD_TYPE_HMAC_MD5:
743 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_2, password,
744 snp_auth);
745 break;
746 }
747 }
748
749 static int isis_instance_domain_password_create(enum nb_event event,
750 const struct lyd_node *dnode,
751 union nb_resource *resource)
752 {
753 /* actual setting is done in apply_finish */
754 return NB_OK;
755 }
756
757 static int isis_instance_domain_password_destroy(enum nb_event event,
758 const struct lyd_node *dnode)
759 {
760 struct isis_area *area;
761
762 if (event != NB_EV_APPLY)
763 return NB_OK;
764
765 area = nb_running_get_entry(dnode, NULL, true);
766 isis_area_passwd_unset(area, IS_LEVEL_2);
767
768 return NB_OK;
769 }
770
771 /*
772 * XPath: /frr-isisd:isis/instance/domain-password/password
773 */
774 static int
775 isis_instance_domain_password_password_modify(enum nb_event event,
776 const struct lyd_node *dnode,
777 union nb_resource *resource)
778 {
779 /* actual setting is done in apply_finish */
780 return NB_OK;
781 }
782
783 /*
784 * XPath: /frr-isisd:isis/instance/domain-password/password-type
785 */
786 static int
787 isis_instance_domain_password_password_type_modify(enum nb_event event,
788 const struct lyd_node *dnode,
789 union nb_resource *resource)
790 {
791 /* actual setting is done in apply_finish */
792 return NB_OK;
793 }
794
795 /*
796 * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
797 */
798 static int isis_instance_domain_password_authenticate_snp_modify(
799 enum nb_event event, const struct lyd_node *dnode,
800 union nb_resource *resource)
801 {
802 /* actual setting is done in apply_finish */
803 return NB_OK;
804 }
805
806 /*
807 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
808 */
809 static void default_info_origin_apply_finish(const struct lyd_node *dnode,
810 int family)
811 {
812 int originate_type = DEFAULT_ORIGINATE;
813 unsigned long metric = 0;
814 const char *routemap = NULL;
815 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
816 int level = yang_dnode_get_enum(dnode, "./level");
817
818 if (yang_dnode_get_bool(dnode, "./always")) {
819 originate_type = DEFAULT_ORIGINATE_ALWAYS;
820 } else if (family == AF_INET6) {
821 zlog_warn(
822 "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
823 __func__);
824 }
825
826 if (yang_dnode_exists(dnode, "./metric"))
827 metric = yang_dnode_get_uint32(dnode, "./metric");
828 if (yang_dnode_exists(dnode, "./route-map"))
829 routemap = yang_dnode_get_string(dnode, "./route-map");
830
831 isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
832 originate_type);
833 }
834
835 static void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
836 {
837 default_info_origin_apply_finish(dnode, AF_INET);
838 }
839
840 static void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
841 {
842 default_info_origin_apply_finish(dnode, AF_INET6);
843 }
844
845 static int isis_instance_default_information_originate_ipv4_create(
846 enum nb_event event, const struct lyd_node *dnode,
847 union nb_resource *resource)
848 {
849 /* It's all done by default_info_origin_apply_finish */
850 return NB_OK;
851 }
852
853 static int isis_instance_default_information_originate_ipv4_destroy(
854 enum nb_event event, const struct lyd_node *dnode)
855 {
856 struct isis_area *area;
857 int level;
858
859 if (event != NB_EV_APPLY)
860 return NB_OK;
861
862 area = nb_running_get_entry(dnode, NULL, true);
863 level = yang_dnode_get_enum(dnode, "./level");
864 isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
865
866 return NB_OK;
867 }
868
869 /*
870 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
871 */
872 static int isis_instance_default_information_originate_ipv4_always_modify(
873 enum nb_event event, const struct lyd_node *dnode,
874 union nb_resource *resource)
875 {
876 /* It's all done by default_info_origin_apply_finish */
877 return NB_OK;
878 }
879
880 /*
881 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
882 */
883 static int isis_instance_default_information_originate_ipv4_route_map_modify(
884 enum nb_event event, const struct lyd_node *dnode,
885 union nb_resource *resource)
886 {
887 /* It's all done by default_info_origin_apply_finish */
888 return NB_OK;
889 }
890
891 static int isis_instance_default_information_originate_ipv4_route_map_destroy(
892 enum nb_event event, const struct lyd_node *dnode)
893 {
894 /* It's all done by default_info_origin_apply_finish */
895 return NB_OK;
896 }
897
898 /*
899 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
900 */
901 static int isis_instance_default_information_originate_ipv4_metric_modify(
902 enum nb_event event, const struct lyd_node *dnode,
903 union nb_resource *resource)
904 {
905 /* It's all done by default_info_origin_apply_finish */
906 return NB_OK;
907 }
908
909 /*
910 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
911 */
912 static int isis_instance_default_information_originate_ipv6_create(
913 enum nb_event event, const struct lyd_node *dnode,
914 union nb_resource *resource)
915 {
916 /* It's all done by default_info_origin_apply_finish */
917 return NB_OK;
918 }
919
920 static int isis_instance_default_information_originate_ipv6_destroy(
921 enum nb_event event, const struct lyd_node *dnode)
922 {
923 struct isis_area *area;
924 int level;
925
926 if (event != NB_EV_APPLY)
927 return NB_OK;
928
929 area = nb_running_get_entry(dnode, NULL, true);
930 level = yang_dnode_get_enum(dnode, "./level");
931 isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
932
933 return NB_OK;
934 }
935
936 /*
937 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
938 */
939 static int isis_instance_default_information_originate_ipv6_always_modify(
940 enum nb_event event, const struct lyd_node *dnode,
941 union nb_resource *resource)
942 {
943 /* It's all done by default_info_origin_apply_finish */
944 return NB_OK;
945 }
946
947 /*
948 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
949 */
950 static int isis_instance_default_information_originate_ipv6_route_map_modify(
951 enum nb_event event, const struct lyd_node *dnode,
952 union nb_resource *resource)
953 {
954 /* It's all done by default_info_origin_apply_finish */
955 return NB_OK;
956 }
957
958 static int isis_instance_default_information_originate_ipv6_route_map_destroy(
959 enum nb_event event, const struct lyd_node *dnode)
960 {
961 /* It's all done by default_info_origin_apply_finish */
962 return NB_OK;
963 }
964
965 /*
966 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
967 */
968 static int isis_instance_default_information_originate_ipv6_metric_modify(
969 enum nb_event event, const struct lyd_node *dnode,
970 union nb_resource *resource)
971 {
972 /* It's all done by default_info_origin_apply_finish */
973 return NB_OK;
974 }
975
976 /*
977 * XPath: /frr-isisd:isis/instance/redistribute/ipv4
978 */
979 static void redistribute_apply_finish(const struct lyd_node *dnode, int family)
980 {
981 assert(family == AF_INET || family == AF_INET6);
982 int type, level;
983 unsigned long metric = 0;
984 const char *routemap = NULL;
985 struct isis_area *area;
986
987 type = yang_dnode_get_enum(dnode, "./protocol");
988 level = yang_dnode_get_enum(dnode, "./level");
989 area = nb_running_get_entry(dnode, NULL, true);
990
991 if (yang_dnode_exists(dnode, "./metric"))
992 metric = yang_dnode_get_uint32(dnode, "./metric");
993 if (yang_dnode_exists(dnode, "./route-map"))
994 routemap = yang_dnode_get_string(dnode, "./route-map");
995
996 isis_redist_set(area, level, family, type, metric, routemap, 0);
997 }
998
999 static void redistribute_ipv4_apply_finish(const struct lyd_node *dnode)
1000 {
1001 redistribute_apply_finish(dnode, AF_INET);
1002 }
1003
1004 static void redistribute_ipv6_apply_finish(const struct lyd_node *dnode)
1005 {
1006 redistribute_apply_finish(dnode, AF_INET6);
1007 }
1008
1009 static int isis_instance_redistribute_ipv4_create(enum nb_event event,
1010 const struct lyd_node *dnode,
1011 union nb_resource *resource)
1012 {
1013 /* It's all done by redistribute_apply_finish */
1014 return NB_OK;
1015 }
1016
1017 static int isis_instance_redistribute_ipv4_destroy(enum nb_event event,
1018 const struct lyd_node *dnode)
1019 {
1020 struct isis_area *area;
1021 int level, type;
1022
1023 if (event != NB_EV_APPLY)
1024 return NB_OK;
1025
1026 area = nb_running_get_entry(dnode, NULL, true);
1027 level = yang_dnode_get_enum(dnode, "./level");
1028 type = yang_dnode_get_enum(dnode, "./protocol");
1029 isis_redist_unset(area, level, AF_INET, type);
1030
1031 return NB_OK;
1032 }
1033
1034 /*
1035 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
1036 */
1037 static int
1038 isis_instance_redistribute_ipv4_route_map_modify(enum nb_event event,
1039 const struct lyd_node *dnode,
1040 union nb_resource *resource)
1041 {
1042 /* It's all done by redistribute_apply_finish */
1043 return NB_OK;
1044 }
1045
1046 static int
1047 isis_instance_redistribute_ipv4_route_map_destroy(enum nb_event event,
1048 const struct lyd_node *dnode)
1049 {
1050 /* It's all done by redistribute_apply_finish */
1051 return NB_OK;
1052 }
1053
1054 /*
1055 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
1056 */
1057 static int
1058 isis_instance_redistribute_ipv4_metric_modify(enum nb_event event,
1059 const struct lyd_node *dnode,
1060 union nb_resource *resource)
1061 {
1062 /* It's all done by redistribute_apply_finish */
1063 return NB_OK;
1064 }
1065
1066 /*
1067 * XPath: /frr-isisd:isis/instance/redistribute/ipv6
1068 */
1069 static int isis_instance_redistribute_ipv6_create(enum nb_event event,
1070 const struct lyd_node *dnode,
1071 union nb_resource *resource)
1072 {
1073 /* It's all done by redistribute_apply_finish */
1074 return NB_OK;
1075 }
1076
1077 static int isis_instance_redistribute_ipv6_destroy(enum nb_event event,
1078 const struct lyd_node *dnode)
1079 {
1080 struct isis_area *area;
1081 int level, type;
1082
1083 if (event != NB_EV_APPLY)
1084 return NB_OK;
1085
1086 area = nb_running_get_entry(dnode, NULL, true);
1087 level = yang_dnode_get_enum(dnode, "./level");
1088 type = yang_dnode_get_enum(dnode, "./protocol");
1089 isis_redist_unset(area, level, AF_INET6, type);
1090
1091 return NB_OK;
1092 }
1093
1094 /*
1095 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
1096 */
1097 static int
1098 isis_instance_redistribute_ipv6_route_map_modify(enum nb_event event,
1099 const struct lyd_node *dnode,
1100 union nb_resource *resource)
1101 {
1102 /* It's all done by redistribute_apply_finish */
1103 return NB_OK;
1104 }
1105
1106 static int
1107 isis_instance_redistribute_ipv6_route_map_destroy(enum nb_event event,
1108 const struct lyd_node *dnode)
1109 {
1110 /* It's all done by redistribute_apply_finish */
1111 return NB_OK;
1112 }
1113
1114 /*
1115 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
1116 */
1117 static int
1118 isis_instance_redistribute_ipv6_metric_modify(enum nb_event event,
1119 const struct lyd_node *dnode,
1120 union nb_resource *resource)
1121 {
1122 /* It's all done by redistribute_apply_finish */
1123 return NB_OK;
1124 }
1125
1126 /*
1127 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
1128 */
1129 static int isis_multi_topology_common(enum nb_event event,
1130 const struct lyd_node *dnode,
1131 const char *topology, bool create)
1132 {
1133 struct isis_area *area;
1134 struct isis_area_mt_setting *setting;
1135 uint16_t mtid = isis_str2mtid(topology);
1136
1137 switch (event) {
1138 case NB_EV_VALIDATE:
1139 if (mtid == (uint16_t)-1) {
1140 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1141 "Unknown topology %s", topology);
1142 return NB_ERR_VALIDATION;
1143 }
1144 break;
1145 case NB_EV_PREPARE:
1146 case NB_EV_ABORT:
1147 break;
1148 case NB_EV_APPLY:
1149 area = nb_running_get_entry(dnode, NULL, true);
1150 setting = area_get_mt_setting(area, mtid);
1151 setting->enabled = create;
1152 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1153 break;
1154 }
1155
1156 return NB_OK;
1157 }
1158
1159 static int isis_multi_topology_overload_common(enum nb_event event,
1160 const struct lyd_node *dnode,
1161 const char *topology)
1162 {
1163 struct isis_area *area;
1164 struct isis_area_mt_setting *setting;
1165 uint16_t mtid = isis_str2mtid(topology);
1166
1167 /* validation is done in isis_multi_topology_common */
1168 if (event != NB_EV_APPLY)
1169 return NB_OK;
1170
1171 area = nb_running_get_entry(dnode, NULL, true);
1172 setting = area_get_mt_setting(area, mtid);
1173 setting->overload = yang_dnode_get_bool(dnode, NULL);
1174 if (setting->enabled)
1175 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1176
1177 return NB_OK;
1178 }
1179
1180 static int
1181 isis_instance_multi_topology_ipv4_multicast_create(enum nb_event event,
1182 const struct lyd_node *dnode,
1183 union nb_resource *resource)
1184 {
1185 return isis_multi_topology_common(event, dnode, "ipv4-multicast", true);
1186 }
1187
1188 static int
1189 isis_instance_multi_topology_ipv4_multicast_destroy(enum nb_event event,
1190 const struct lyd_node *dnode)
1191 {
1192 return isis_multi_topology_common(event, dnode, "ipv4-multicast",
1193 false);
1194 }
1195
1196 /*
1197 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
1198 */
1199 static int isis_instance_multi_topology_ipv4_multicast_overload_modify(
1200 enum nb_event event, const struct lyd_node *dnode,
1201 union nb_resource *resource)
1202 {
1203 return isis_multi_topology_overload_common(event, dnode,
1204 "ipv4-multicast");
1205 }
1206
1207 /*
1208 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
1209 */
1210 static int isis_instance_multi_topology_ipv4_management_create(
1211 enum nb_event event, const struct lyd_node *dnode,
1212 union nb_resource *resource)
1213 {
1214 return isis_multi_topology_common(event, dnode, "ipv4-mgmt", true);
1215 }
1216
1217 static int isis_instance_multi_topology_ipv4_management_destroy(
1218 enum nb_event event, const struct lyd_node *dnode)
1219 {
1220 return isis_multi_topology_common(event, dnode, "ipv4-mgmt", false);
1221 }
1222
1223 /*
1224 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
1225 */
1226 static int isis_instance_multi_topology_ipv4_management_overload_modify(
1227 enum nb_event event, const struct lyd_node *dnode,
1228 union nb_resource *resource)
1229 {
1230 return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt");
1231 }
1232
1233 /*
1234 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
1235 */
1236 static int
1237 isis_instance_multi_topology_ipv6_unicast_create(enum nb_event event,
1238 const struct lyd_node *dnode,
1239 union nb_resource *resource)
1240 {
1241 return isis_multi_topology_common(event, dnode, "ipv6-unicast", true);
1242 }
1243
1244 static int
1245 isis_instance_multi_topology_ipv6_unicast_destroy(enum nb_event event,
1246 const struct lyd_node *dnode)
1247 {
1248 return isis_multi_topology_common(event, dnode, "ipv6-unicast", false);
1249 }
1250
1251 /*
1252 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
1253 */
1254 static int isis_instance_multi_topology_ipv6_unicast_overload_modify(
1255 enum nb_event event, const struct lyd_node *dnode,
1256 union nb_resource *resource)
1257 {
1258 return isis_multi_topology_overload_common(event, dnode,
1259 "ipv6-unicast");
1260 }
1261
1262 /*
1263 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
1264 */
1265 static int
1266 isis_instance_multi_topology_ipv6_multicast_create(enum nb_event event,
1267 const struct lyd_node *dnode,
1268 union nb_resource *resource)
1269 {
1270 return isis_multi_topology_common(event, dnode, "ipv6-multicast", true);
1271 }
1272
1273 static int
1274 isis_instance_multi_topology_ipv6_multicast_destroy(enum nb_event event,
1275 const struct lyd_node *dnode)
1276 {
1277 return isis_multi_topology_common(event, dnode, "ipv6-multicast",
1278 false);
1279 }
1280
1281 /*
1282 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
1283 */
1284 static int isis_instance_multi_topology_ipv6_multicast_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,
1289 "ipv6-multicast");
1290 }
1291
1292 /*
1293 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
1294 */
1295 static int isis_instance_multi_topology_ipv6_management_create(
1296 enum nb_event event, const struct lyd_node *dnode,
1297 union nb_resource *resource)
1298 {
1299 return isis_multi_topology_common(event, dnode, "ipv6-mgmt", true);
1300 }
1301
1302 static int isis_instance_multi_topology_ipv6_management_destroy(
1303 enum nb_event event, const struct lyd_node *dnode)
1304 {
1305 return isis_multi_topology_common(event, dnode, "ipv6-mgmt", false);
1306 }
1307
1308 /*
1309 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
1310 */
1311 static int isis_instance_multi_topology_ipv6_management_overload_modify(
1312 enum nb_event event, const struct lyd_node *dnode,
1313 union nb_resource *resource)
1314 {
1315 return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt");
1316 }
1317
1318 /*
1319 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
1320 */
1321 static int
1322 isis_instance_multi_topology_ipv6_dstsrc_create(enum nb_event event,
1323 const struct lyd_node *dnode,
1324 union nb_resource *resource)
1325 {
1326 return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", true);
1327 }
1328
1329 static int
1330 isis_instance_multi_topology_ipv6_dstsrc_destroy(enum nb_event event,
1331 const struct lyd_node *dnode)
1332 {
1333 return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", false);
1334 }
1335
1336 /*
1337 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
1338 */
1339 static int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
1340 enum nb_event event, const struct lyd_node *dnode,
1341 union nb_resource *resource)
1342 {
1343 return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc");
1344 }
1345
1346 /*
1347 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1348 */
1349 static int
1350 isis_instance_log_adjacency_changes_modify(enum nb_event event,
1351 const struct lyd_node *dnode,
1352 union nb_resource *resource)
1353 {
1354 struct isis_area *area;
1355 bool log = yang_dnode_get_bool(dnode, NULL);
1356
1357 if (event != NB_EV_APPLY)
1358 return NB_OK;
1359
1360 area = nb_running_get_entry(dnode, NULL, true);
1361 area->log_adj_changes = log ? 1 : 0;
1362
1363 return NB_OK;
1364 }
1365
1366 /*
1367 * XPath: /frr-isisd:isis/instance/mpls-te
1368 */
1369 static int isis_instance_mpls_te_create(enum nb_event event,
1370 const struct lyd_node *dnode,
1371 union nb_resource *resource)
1372 {
1373 struct listnode *node;
1374 struct isis_area *area;
1375 struct isis_circuit *circuit;
1376
1377 if (event != NB_EV_APPLY)
1378 return NB_OK;
1379
1380 area = nb_running_get_entry(dnode, NULL, true);
1381 if (area->mta == NULL) {
1382
1383 struct mpls_te_area *new;
1384
1385 zlog_debug("ISIS MPLS-TE: Initialize area %s",
1386 area->area_tag);
1387
1388 new = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_area));
1389
1390 /* Initialize MPLS_TE structure */
1391 new->status = enable;
1392 new->level = 0;
1393 new->inter_as = off;
1394 new->interas_areaid.s_addr = 0;
1395 new->router_id.s_addr = 0;
1396
1397 area->mta = new;
1398 } else {
1399 area->mta->status = enable;
1400 }
1401
1402 /*
1403 * Following code is intended to handle two cases;
1404 *
1405 * 1) MPLS-TE was disabled at startup time, but now become enabled.
1406 * In this case, we must enable MPLS-TE Circuit regarding interface
1407 * MPLS_TE flag
1408 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1409 */
1410 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
1411 if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
1412 continue;
1413
1414 if (!IS_MPLS_TE(circuit->mtc)
1415 && HAS_LINK_PARAMS(circuit->interface))
1416 circuit->mtc->status = enable;
1417 else
1418 continue;
1419
1420 /* Reoriginate STD_TE & GMPLS circuits */
1421 if (circuit->area)
1422 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1423 0);
1424 }
1425
1426 return NB_OK;
1427 }
1428
1429 static int isis_instance_mpls_te_destroy(enum nb_event event,
1430 const struct lyd_node *dnode)
1431 {
1432 struct listnode *node;
1433 struct isis_area *area;
1434 struct isis_circuit *circuit;
1435
1436 if (event != NB_EV_APPLY)
1437 return NB_OK;
1438
1439 area = nb_running_get_entry(dnode, NULL, true);
1440 if (IS_MPLS_TE(area->mta))
1441 area->mta->status = disable;
1442 else
1443 return NB_OK;
1444
1445 /* Flush LSP if circuit engage */
1446 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
1447 if (circuit->mtc == NULL || (circuit->mtc->status == disable))
1448 continue;
1449
1450 /* disable MPLS_TE Circuit */
1451 circuit->mtc->status = disable;
1452
1453 /* Re-originate circuit without STD_TE & GMPLS parameters */
1454 if (circuit->area)
1455 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1456 0);
1457 }
1458
1459 return NB_OK;
1460 }
1461
1462 /*
1463 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
1464 */
1465 static int isis_instance_mpls_te_router_address_modify(enum nb_event event,
1466 const struct lyd_node *dnode,
1467 union nb_resource *resource)
1468 {
1469 struct in_addr value;
1470 struct isis_area *area;
1471
1472 if (event != NB_EV_APPLY)
1473 return NB_OK;
1474
1475 area = nb_running_get_entry(dnode, NULL, true);
1476 /* only proceed if MPLS-TE is enabled */
1477 if (!IS_MPLS_TE(area->mta))
1478 return NB_OK;
1479
1480 /* Update Area Router ID */
1481 yang_dnode_get_ipv4(&value, dnode, NULL);
1482 area->mta->router_id.s_addr = value.s_addr;
1483
1484 /* And re-schedule LSP update */
1485 if (listcount(area->area_addrs) > 0)
1486 lsp_regenerate_schedule(area, area->is_type, 0);
1487
1488 return NB_OK;
1489 }
1490
1491 static int isis_instance_mpls_te_router_address_destroy(enum nb_event event,
1492 const struct lyd_node *dnode)
1493 {
1494 struct isis_area *area;
1495
1496 if (event != NB_EV_APPLY)
1497 return NB_OK;
1498
1499 area = nb_running_get_entry(dnode, NULL, true);
1500 /* only proceed if MPLS-TE is enabled */
1501 if (!IS_MPLS_TE(area->mta))
1502 return NB_OK;
1503
1504 /* Reset Area Router ID */
1505 area->mta->router_id.s_addr = INADDR_ANY;
1506
1507 /* And re-schedule LSP update */
1508 if (listcount(area->area_addrs) > 0)
1509 lsp_regenerate_schedule(area, area->is_type, 0);
1510
1511 return NB_OK;
1512 }
1513
1514 /*
1515 * XPath: /frr-interface:lib/interface/frr-isisd:isis
1516 */
1517 static int lib_interface_isis_create(enum nb_event event,
1518 const struct lyd_node *dnode,
1519 union nb_resource *resource)
1520 {
1521 struct isis_area *area;
1522 struct interface *ifp;
1523 struct isis_circuit *circuit;
1524 const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
1525
1526 if (event != NB_EV_APPLY)
1527 return NB_OK;
1528
1529 area = isis_area_lookup(area_tag);
1530 /* The area should have already be created. We are
1531 * setting the priority of the global isis area creation
1532 * slightly lower, so it should be executed first, but I
1533 * cannot rely on that so here I have to check.
1534 */
1535 if (!area) {
1536 flog_err(
1537 EC_LIB_NB_CB_CONFIG_APPLY,
1538 "%s: attempt to create circuit for area %s before the area has been created",
1539 __func__, area_tag);
1540 abort();
1541 }
1542
1543 ifp = nb_running_get_entry(dnode, NULL, true);
1544 circuit = isis_circuit_create(area, ifp);
1545 assert(circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
1546 nb_running_set_entry(dnode, circuit);
1547
1548 return NB_OK;
1549 }
1550
1551 static int lib_interface_isis_destroy(enum nb_event event,
1552 const struct lyd_node *dnode)
1553 {
1554 struct isis_circuit *circuit;
1555
1556 if (event != NB_EV_APPLY)
1557 return NB_OK;
1558
1559 circuit = nb_running_unset_entry(dnode);
1560 if (!circuit)
1561 return NB_ERR_INCONSISTENCY;
1562 /* delete circuit through csm changes */
1563 switch (circuit->state) {
1564 case C_STATE_UP:
1565 isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
1566 circuit->interface);
1567 isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
1568 break;
1569 case C_STATE_CONF:
1570 isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
1571 break;
1572 case C_STATE_INIT:
1573 isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
1574 circuit->interface);
1575 break;
1576 }
1577
1578 return NB_OK;
1579 }
1580
1581 /*
1582 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1583 */
1584 static int lib_interface_isis_area_tag_modify(enum nb_event event,
1585 const struct lyd_node *dnode,
1586 union nb_resource *resource)
1587 {
1588 struct isis_circuit *circuit;
1589 struct interface *ifp;
1590 struct vrf *vrf;
1591 const char *area_tag, *ifname, *vrfname;
1592
1593 if (event == NB_EV_VALIDATE) {
1594 /* libyang doesn't like relative paths across module boundaries
1595 */
1596 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1597 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1598 vrf = vrf_lookup_by_name(vrfname);
1599 assert(vrf);
1600 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1601 if (!ifp)
1602 return NB_OK;
1603 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1604 area_tag = yang_dnode_get_string(dnode, NULL);
1605 if (circuit && circuit->area && circuit->area->area_tag
1606 && strcmp(circuit->area->area_tag, area_tag)) {
1607 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1608 "ISIS circuit is already defined on %s",
1609 circuit->area->area_tag);
1610 return NB_ERR_VALIDATION;
1611 }
1612 }
1613
1614 return NB_OK;
1615 }
1616
1617 /*
1618 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1619 */
1620 static int lib_interface_isis_circuit_type_modify(enum nb_event event,
1621 const struct lyd_node *dnode,
1622 union nb_resource *resource)
1623 {
1624 int circ_type = yang_dnode_get_enum(dnode, NULL);
1625 struct isis_circuit *circuit;
1626 struct interface *ifp;
1627 struct vrf *vrf;
1628 const char *ifname, *vrfname;
1629
1630 switch (event) {
1631 case NB_EV_VALIDATE:
1632 /* libyang doesn't like relative paths across module boundaries
1633 */
1634 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1635 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1636 vrf = vrf_lookup_by_name(vrfname);
1637 assert(vrf);
1638 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1639 if (!ifp)
1640 break;
1641 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1642 if (circuit && circuit->state == C_STATE_UP
1643 && circuit->area->is_type != IS_LEVEL_1_AND_2
1644 && circuit->area->is_type != circ_type) {
1645 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1646 "Invalid circuit level for area %s",
1647 circuit->area->area_tag);
1648 return NB_ERR_VALIDATION;
1649 }
1650 break;
1651 case NB_EV_PREPARE:
1652 case NB_EV_ABORT:
1653 break;
1654 case NB_EV_APPLY:
1655 circuit = nb_running_get_entry(dnode, NULL, true);
1656 isis_circuit_is_type_set(circuit, circ_type);
1657 break;
1658 }
1659
1660 return NB_OK;
1661 }
1662
1663 /*
1664 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1665 */
1666 static int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
1667 const struct lyd_node *dnode,
1668 union nb_resource *resource)
1669 {
1670 bool ipv4, ipv6;
1671 struct isis_circuit *circuit;
1672
1673 if (event != NB_EV_APPLY)
1674 return NB_OK;
1675
1676 circuit = nb_running_get_entry(dnode, NULL, true);
1677 ipv4 = yang_dnode_get_bool(dnode, NULL);
1678 ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
1679 isis_circuit_af_set(circuit, ipv4, ipv6);
1680
1681 return NB_OK;
1682 }
1683
1684 /*
1685 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1686 */
1687 static int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
1688 const struct lyd_node *dnode,
1689 union nb_resource *resource)
1690 {
1691 bool ipv4, ipv6;
1692 struct isis_circuit *circuit;
1693
1694 if (event != NB_EV_APPLY)
1695 return NB_OK;
1696
1697 circuit = nb_running_get_entry(dnode, NULL, true);
1698 ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
1699 ipv6 = yang_dnode_get_bool(dnode, NULL);
1700 isis_circuit_af_set(circuit, ipv4, ipv6);
1701
1702 return NB_OK;
1703 }
1704
1705 /*
1706 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1707 */
1708 static int
1709 lib_interface_isis_csnp_interval_level_1_modify(enum nb_event event,
1710 const struct lyd_node *dnode,
1711 union nb_resource *resource)
1712 {
1713 struct isis_circuit *circuit;
1714
1715 if (event != NB_EV_APPLY)
1716 return NB_OK;
1717
1718 circuit = nb_running_get_entry(dnode, NULL, true);
1719 circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1720
1721 return NB_OK;
1722 }
1723
1724 /*
1725 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1726 */
1727 static int
1728 lib_interface_isis_csnp_interval_level_2_modify(enum nb_event event,
1729 const struct lyd_node *dnode,
1730 union nb_resource *resource)
1731 {
1732 struct isis_circuit *circuit;
1733
1734 if (event != NB_EV_APPLY)
1735 return NB_OK;
1736
1737 circuit = nb_running_get_entry(dnode, NULL, true);
1738 circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1739
1740 return NB_OK;
1741 }
1742
1743 /*
1744 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1745 */
1746 static int
1747 lib_interface_isis_psnp_interval_level_1_modify(enum nb_event event,
1748 const struct lyd_node *dnode,
1749 union nb_resource *resource)
1750 {
1751 struct isis_circuit *circuit;
1752
1753 if (event != NB_EV_APPLY)
1754 return NB_OK;
1755
1756 circuit = nb_running_get_entry(dnode, NULL, true);
1757 circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1758
1759 return NB_OK;
1760 }
1761
1762 /*
1763 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1764 */
1765 static int
1766 lib_interface_isis_psnp_interval_level_2_modify(enum nb_event event,
1767 const struct lyd_node *dnode,
1768 union nb_resource *resource)
1769 {
1770 struct isis_circuit *circuit;
1771
1772 if (event != NB_EV_APPLY)
1773 return NB_OK;
1774
1775 circuit = nb_running_get_entry(dnode, NULL, true);
1776 circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1777
1778 return NB_OK;
1779 }
1780
1781 /*
1782 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1783 */
1784 static int lib_interface_isis_hello_padding_modify(enum nb_event event,
1785 const struct lyd_node *dnode,
1786 union nb_resource *resource)
1787 {
1788 struct isis_circuit *circuit;
1789
1790 if (event != NB_EV_APPLY)
1791 return NB_OK;
1792
1793 circuit = nb_running_get_entry(dnode, NULL, true);
1794 circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL);
1795
1796 return NB_OK;
1797 }
1798
1799 /*
1800 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1801 */
1802 static int
1803 lib_interface_isis_hello_interval_level_1_modify(enum nb_event event,
1804 const struct lyd_node *dnode,
1805 union nb_resource *resource)
1806 {
1807 struct isis_circuit *circuit;
1808 uint32_t interval;
1809
1810 if (event != NB_EV_APPLY)
1811 return NB_OK;
1812
1813 circuit = nb_running_get_entry(dnode, NULL, true);
1814 interval = yang_dnode_get_uint32(dnode, NULL);
1815 circuit->hello_interval[0] = interval;
1816
1817 return NB_OK;
1818 }
1819
1820 /*
1821 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1822 */
1823 static int
1824 lib_interface_isis_hello_interval_level_2_modify(enum nb_event event,
1825 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 static int
1845 lib_interface_isis_hello_multiplier_level_1_modify(enum nb_event event,
1846 const struct lyd_node *dnode,
1847 union nb_resource *resource)
1848 {
1849 struct isis_circuit *circuit;
1850 uint16_t multi;
1851
1852 if (event != NB_EV_APPLY)
1853 return NB_OK;
1854
1855 circuit = nb_running_get_entry(dnode, NULL, true);
1856 multi = yang_dnode_get_uint16(dnode, NULL);
1857 circuit->hello_multiplier[0] = multi;
1858
1859 return NB_OK;
1860 }
1861
1862 /*
1863 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1864 */
1865 static int
1866 lib_interface_isis_hello_multiplier_level_2_modify(enum nb_event event,
1867 const struct lyd_node *dnode,
1868 union nb_resource *resource)
1869 {
1870 struct isis_circuit *circuit;
1871 uint16_t multi;
1872
1873 if (event != NB_EV_APPLY)
1874 return NB_OK;
1875
1876 circuit = nb_running_get_entry(dnode, NULL, true);
1877 multi = yang_dnode_get_uint16(dnode, NULL);
1878 circuit->hello_multiplier[1] = multi;
1879
1880 return NB_OK;
1881 }
1882
1883 /*
1884 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1885 */
1886 static int
1887 lib_interface_isis_metric_level_1_modify(enum nb_event event,
1888 const struct lyd_node *dnode,
1889 union nb_resource *resource)
1890 {
1891 struct isis_circuit *circuit;
1892 unsigned int met;
1893
1894 if (event != NB_EV_APPLY)
1895 return NB_OK;
1896
1897 circuit = nb_running_get_entry(dnode, NULL, true);
1898 met = yang_dnode_get_uint32(dnode, NULL);
1899 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
1900
1901 return NB_OK;
1902 }
1903
1904 /*
1905 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1906 */
1907 static int
1908 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 static int
1929 lib_interface_isis_priority_level_1_modify(enum nb_event event,
1930 const struct lyd_node *dnode,
1931 union nb_resource *resource)
1932 {
1933 struct isis_circuit *circuit;
1934
1935 if (event != NB_EV_APPLY)
1936 return NB_OK;
1937
1938 circuit = nb_running_get_entry(dnode, NULL, true);
1939 circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
1940
1941 return NB_OK;
1942 }
1943
1944 /*
1945 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1946 */
1947 static int
1948 lib_interface_isis_priority_level_2_modify(enum nb_event event,
1949 const struct lyd_node *dnode,
1950 union nb_resource *resource)
1951 {
1952 struct isis_circuit *circuit;
1953
1954 if (event != NB_EV_APPLY)
1955 return NB_OK;
1956
1957 circuit = nb_running_get_entry(dnode, NULL, true);
1958 circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
1959
1960 return NB_OK;
1961 }
1962
1963 /*
1964 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1965 */
1966 static int lib_interface_isis_network_type_modify(enum nb_event event,
1967 const struct lyd_node *dnode,
1968 union nb_resource *resource)
1969 {
1970 struct isis_circuit *circuit;
1971 int net_type = yang_dnode_get_enum(dnode, NULL);
1972
1973 switch (event) {
1974 case NB_EV_VALIDATE:
1975 circuit = nb_running_get_entry(dnode, NULL, false);
1976 if (!circuit)
1977 break;
1978 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
1979 flog_warn(
1980 EC_LIB_NB_CB_CONFIG_VALIDATE,
1981 "Cannot change network type on loopback interface");
1982 return NB_ERR_VALIDATION;
1983 }
1984 if (net_type == CIRCUIT_T_BROADCAST
1985 && circuit->state == C_STATE_UP
1986 && !if_is_broadcast(circuit->interface)) {
1987 flog_warn(
1988 EC_LIB_NB_CB_CONFIG_VALIDATE,
1989 "Cannot configure non-broadcast interface for broadcast operation");
1990 return NB_ERR_VALIDATION;
1991 }
1992 break;
1993 case NB_EV_PREPARE:
1994 case NB_EV_ABORT:
1995 break;
1996 case NB_EV_APPLY:
1997 circuit = nb_running_get_entry(dnode, NULL, true);
1998 isis_circuit_circ_type_set(circuit, net_type);
1999 break;
2000 }
2001
2002 return NB_OK;
2003 }
2004
2005 /*
2006 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2007 */
2008 static int lib_interface_isis_passive_modify(enum nb_event event,
2009 const struct lyd_node *dnode,
2010 union nb_resource *resource)
2011 {
2012 struct isis_circuit *circuit;
2013 struct isis_area *area;
2014 struct interface *ifp;
2015 bool passive = yang_dnode_get_bool(dnode, NULL);
2016
2017 /* validation only applies if we are setting passive to false */
2018 if (!passive && event == NB_EV_VALIDATE) {
2019 circuit = nb_running_get_entry(dnode, NULL, false);
2020 if (!circuit)
2021 return NB_OK;
2022 ifp = circuit->interface;
2023 if (!ifp)
2024 return NB_OK;
2025 if (if_is_loopback(ifp)) {
2026 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
2027 "Loopback is always passive");
2028 return NB_ERR_VALIDATION;
2029 }
2030 }
2031
2032 if (event != NB_EV_APPLY)
2033 return NB_OK;
2034
2035 circuit = nb_running_get_entry(dnode, NULL, true);
2036 if (circuit->state != C_STATE_UP) {
2037 circuit->is_passive = passive;
2038 } else {
2039 area = circuit->area;
2040 isis_csm_state_change(ISIS_DISABLE, circuit, area);
2041 circuit->is_passive = passive;
2042 isis_csm_state_change(ISIS_ENABLE, circuit, area);
2043 }
2044
2045 return NB_OK;
2046 }
2047
2048 /*
2049 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2050 */
2051 static int lib_interface_isis_password_create(enum nb_event event,
2052 const struct lyd_node *dnode,
2053 union nb_resource *resource)
2054 {
2055 return NB_OK;
2056 }
2057
2058 static int lib_interface_isis_password_destroy(enum nb_event event,
2059 const struct lyd_node *dnode)
2060 {
2061 struct isis_circuit *circuit;
2062
2063 if (event != NB_EV_APPLY)
2064 return NB_OK;
2065
2066 circuit = nb_running_get_entry(dnode, NULL, true);
2067 isis_circuit_passwd_unset(circuit);
2068
2069 return NB_OK;
2070 }
2071
2072 /*
2073 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2074 */
2075 static int
2076 lib_interface_isis_password_password_modify(enum nb_event event,
2077 const struct lyd_node *dnode,
2078 union nb_resource *resource)
2079 {
2080 struct isis_circuit *circuit;
2081 const char *password;
2082
2083 if (event != NB_EV_APPLY)
2084 return NB_OK;
2085
2086 password = yang_dnode_get_string(dnode, NULL);
2087 circuit = nb_running_get_entry(dnode, NULL, true);
2088
2089 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
2090
2091 return NB_OK;
2092 }
2093
2094 /*
2095 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2096 */
2097 static int
2098 lib_interface_isis_password_password_type_modify(enum nb_event event,
2099 const struct lyd_node *dnode,
2100 union nb_resource *resource)
2101 {
2102 struct isis_circuit *circuit;
2103 uint8_t pass_type;
2104
2105 if (event != NB_EV_APPLY)
2106 return NB_OK;
2107
2108 pass_type = yang_dnode_get_enum(dnode, NULL);
2109 circuit = nb_running_get_entry(dnode, NULL, true);
2110 circuit->passwd.type = pass_type;
2111
2112 return NB_OK;
2113 }
2114
2115 /*
2116 * XPath:
2117 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2118 */
2119 static int lib_interface_isis_disable_three_way_handshake_modify(
2120 enum nb_event event, const struct lyd_node *dnode,
2121 union nb_resource *resource)
2122 {
2123 struct isis_circuit *circuit;
2124
2125 if (event != NB_EV_APPLY)
2126 return NB_OK;
2127
2128 circuit = nb_running_get_entry(dnode, NULL, true);
2129 circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
2130
2131 return NB_OK;
2132 }
2133
2134 /*
2135 * XPath:
2136 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2137 */
2138 static int lib_interface_isis_multi_topology_common(
2139 enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
2140 {
2141 struct isis_circuit *circuit;
2142 bool value;
2143
2144 switch (event) {
2145 case NB_EV_VALIDATE:
2146 circuit = nb_running_get_entry(dnode, NULL, false);
2147 if (circuit && circuit->area && circuit->area->oldmetric) {
2148 flog_warn(
2149 EC_LIB_NB_CB_CONFIG_VALIDATE,
2150 "Multi topology IS-IS can only be used with wide metrics");
2151 return NB_ERR_VALIDATION;
2152 }
2153 break;
2154 case NB_EV_PREPARE:
2155 case NB_EV_ABORT:
2156 break;
2157 case NB_EV_APPLY:
2158 circuit = nb_running_get_entry(dnode, NULL, true);
2159 value = yang_dnode_get_bool(dnode, NULL);
2160 isis_circuit_mt_enabled_set(circuit, mtid, value);
2161 break;
2162 }
2163
2164 return NB_OK;
2165 }
2166
2167 static int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2168 enum nb_event event, const struct lyd_node *dnode,
2169 union nb_resource *resource)
2170 {
2171 return lib_interface_isis_multi_topology_common(event, dnode,
2172 ISIS_MT_IPV4_UNICAST);
2173 }
2174
2175 /*
2176 * XPath:
2177 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2178 */
2179 static int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2180 enum nb_event event, const struct lyd_node *dnode,
2181 union nb_resource *resource)
2182 {
2183 return lib_interface_isis_multi_topology_common(event, dnode,
2184 ISIS_MT_IPV4_MULTICAST);
2185 }
2186
2187 /*
2188 * XPath:
2189 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2190 */
2191 static int lib_interface_isis_multi_topology_ipv4_management_modify(
2192 enum nb_event event, const struct lyd_node *dnode,
2193 union nb_resource *resource)
2194 {
2195 return lib_interface_isis_multi_topology_common(event, dnode,
2196 ISIS_MT_IPV4_MGMT);
2197 }
2198
2199 /*
2200 * XPath:
2201 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2202 */
2203 static int lib_interface_isis_multi_topology_ipv6_unicast_modify(
2204 enum nb_event event, const struct lyd_node *dnode,
2205 union nb_resource *resource)
2206 {
2207 return lib_interface_isis_multi_topology_common(event, dnode,
2208 ISIS_MT_IPV6_UNICAST);
2209 }
2210
2211 /*
2212 * XPath:
2213 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2214 */
2215 static int lib_interface_isis_multi_topology_ipv6_multicast_modify(
2216 enum nb_event event, const struct lyd_node *dnode,
2217 union nb_resource *resource)
2218 {
2219 return lib_interface_isis_multi_topology_common(event, dnode,
2220 ISIS_MT_IPV6_MULTICAST);
2221 }
2222
2223 /*
2224 * XPath:
2225 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2226 */
2227 static int lib_interface_isis_multi_topology_ipv6_management_modify(
2228 enum nb_event event, const struct lyd_node *dnode,
2229 union nb_resource *resource)
2230 {
2231 return lib_interface_isis_multi_topology_common(event, dnode,
2232 ISIS_MT_IPV6_MGMT);
2233 }
2234
2235 /*
2236 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2237 */
2238 static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2239 enum nb_event event, const struct lyd_node *dnode,
2240 union nb_resource *resource)
2241 {
2242 return lib_interface_isis_multi_topology_common(event, dnode,
2243 ISIS_MT_IPV6_DSTSRC);
2244 }
2245
2246 /*
2247 * NOTIFICATIONS
2248 */
2249 static void notif_prep_instance_hdr(const char *xpath,
2250 const struct isis_area *area,
2251 const char *routing_instance,
2252 struct list *args)
2253 {
2254 char xpath_arg[XPATH_MAXLEN];
2255 struct yang_data *data;
2256
2257 snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-instance", xpath);
2258 data = yang_data_new_string(xpath_arg, routing_instance);
2259 listnode_add(args, data);
2260 snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-protocol-name",
2261 xpath);
2262 data = yang_data_new_string(xpath_arg, area->area_tag);
2263 listnode_add(args, data);
2264 snprintf(xpath_arg, sizeof(xpath_arg), "%s/isis-level", xpath);
2265 data = yang_data_new_enum(xpath_arg, area->is_type);
2266 listnode_add(args, data);
2267 }
2268
2269 static void notif_prepr_iface_hdr(const char *xpath,
2270 const struct isis_circuit *circuit,
2271 struct list *args)
2272 {
2273 char xpath_arg[XPATH_MAXLEN];
2274 struct yang_data *data;
2275
2276 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
2277 data = yang_data_new_string(xpath_arg, circuit->interface->name);
2278 listnode_add(args, data);
2279 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-level", xpath);
2280 data = yang_data_new_enum(xpath_arg, circuit->is_type);
2281 listnode_add(args, data);
2282 snprintf(xpath_arg, sizeof(xpath_arg), "%s/extended-circuit-id", xpath);
2283 /* we do not seem to have the extended version of the circuit_id */
2284 data = yang_data_new_uint32(xpath_arg, (uint32_t)circuit->circuit_id);
2285 listnode_add(args, data);
2286 }
2287
2288 /*
2289 * XPath:
2290 * /frr-isisd:database-overload
2291 */
2292 void isis_notif_db_overload(const struct isis_area *area, bool overload)
2293 {
2294 const char *xpath = "/frr-isisd:database-overload";
2295 struct list *arguments = yang_data_list_new();
2296 char xpath_arg[XPATH_MAXLEN];
2297 struct yang_data *data;
2298
2299 notif_prep_instance_hdr(xpath, area, "default", arguments);
2300 snprintf(xpath_arg, sizeof(xpath_arg), "%s/overload", xpath);
2301 data = yang_data_new_enum(xpath_arg, !!overload);
2302 listnode_add(arguments, data);
2303
2304 nb_notification_send(xpath, arguments);
2305 }
2306
2307 /*
2308 * XPath:
2309 * /frr-isisd:lsp-too-large
2310 */
2311 void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
2312 uint32_t pdu_size, const char *lsp_id)
2313 {
2314 const char *xpath = "/frr-isisd:lsp-too-large";
2315 struct list *arguments = yang_data_list_new();
2316 char xpath_arg[XPATH_MAXLEN];
2317 struct yang_data *data;
2318 struct isis_area *area = circuit->area;
2319
2320 notif_prep_instance_hdr(xpath, area, "default", arguments);
2321 notif_prepr_iface_hdr(xpath, circuit, arguments);
2322 snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-size", xpath);
2323 data = yang_data_new_uint32(xpath_arg, pdu_size);
2324 listnode_add(arguments, data);
2325 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2326 data = yang_data_new_string(xpath_arg, lsp_id);
2327 listnode_add(arguments, data);
2328
2329 nb_notification_send(xpath, arguments);
2330 }
2331
2332 /*
2333 * XPath:
2334 * /frr-isisd:if-state-change
2335 */
2336 void isis_notif_if_state_change(const struct isis_circuit *circuit, bool down)
2337 {
2338 const char *xpath = "/frr-isisd:if-state-change";
2339 struct list *arguments = yang_data_list_new();
2340 char xpath_arg[XPATH_MAXLEN];
2341 struct yang_data *data;
2342 struct isis_area *area = circuit->area;
2343
2344 notif_prep_instance_hdr(xpath, area, "default", arguments);
2345 notif_prepr_iface_hdr(xpath, circuit, arguments);
2346 snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
2347 data = yang_data_new_enum(xpath_arg, !!down);
2348 listnode_add(arguments, data);
2349
2350 nb_notification_send(xpath, arguments);
2351 }
2352
2353 /*
2354 * XPath:
2355 * /frr-isisd:corrupted-lsp-detected
2356 */
2357 void isis_notif_corrupted_lsp(const struct isis_area *area, const char *lsp_id)
2358 {
2359 const char *xpath = "/frr-isisd:corrupted-lsp-detected";
2360 struct list *arguments = yang_data_list_new();
2361 char xpath_arg[XPATH_MAXLEN];
2362 struct yang_data *data;
2363
2364 notif_prep_instance_hdr(xpath, area, "default", arguments);
2365 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2366 data = yang_data_new_string(xpath_arg, lsp_id);
2367 listnode_add(arguments, data);
2368
2369 nb_notification_send(xpath, arguments);
2370 }
2371
2372 /*
2373 * XPath:
2374 * /frr-isisd:attempt-to-exceed-max-sequence
2375 */
2376 void isis_notif_lsp_exceed_max(const struct isis_area *area, const char *lsp_id)
2377 {
2378 const char *xpath = "/frr-isisd:attempt-to-exceed-max-sequence";
2379 struct list *arguments = yang_data_list_new();
2380 char xpath_arg[XPATH_MAXLEN];
2381 struct yang_data *data;
2382
2383 notif_prep_instance_hdr(xpath, area, "default", arguments);
2384 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2385 data = yang_data_new_string(xpath_arg, lsp_id);
2386 listnode_add(arguments, data);
2387
2388 nb_notification_send(xpath, arguments);
2389 }
2390
2391 /*
2392 * XPath:
2393 * /frr-isisd:max-area-addresses-mismatch
2394 */
2395 void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
2396 uint8_t max_area_addrs,
2397 const char *raw_pdu)
2398 {
2399 const char *xpath = "/frr-isisd:max-area-addresses-mismatch";
2400 struct list *arguments = yang_data_list_new();
2401 char xpath_arg[XPATH_MAXLEN];
2402 struct yang_data *data;
2403 struct isis_area *area = circuit->area;
2404
2405 notif_prep_instance_hdr(xpath, area, "default", arguments);
2406 notif_prepr_iface_hdr(xpath, circuit, arguments);
2407 snprintf(xpath_arg, sizeof(xpath_arg), "%s/max-area-addresses", xpath);
2408 data = yang_data_new_uint8(xpath_arg, max_area_addrs);
2409 listnode_add(arguments, data);
2410 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2411 data = yang_data_new(xpath_arg, raw_pdu);
2412 listnode_add(arguments, data);
2413
2414 nb_notification_send(xpath, arguments);
2415 }
2416
2417 /*
2418 * XPath:
2419 * /frr-isisd:authentication-type-failure
2420 */
2421 void isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
2422 const char *raw_pdu)
2423 {
2424 const char *xpath = "/frr-isisd:authentication-type-failure";
2425 struct list *arguments = yang_data_list_new();
2426 char xpath_arg[XPATH_MAXLEN];
2427 struct yang_data *data;
2428 struct isis_area *area = circuit->area;
2429
2430 notif_prep_instance_hdr(xpath, area, "default", arguments);
2431 notif_prepr_iface_hdr(xpath, circuit, arguments);
2432 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2433 data = yang_data_new(xpath_arg, raw_pdu);
2434 listnode_add(arguments, data);
2435
2436 nb_notification_send(xpath, arguments);
2437 }
2438
2439 /*
2440 * XPath:
2441 * /frr-isisd:authentication-failure
2442 */
2443 void isis_notif_authentication_failure(const struct isis_circuit *circuit,
2444 const char *raw_pdu)
2445 {
2446 const char *xpath = "/frr-isisd:authentication-failure";
2447 struct list *arguments = yang_data_list_new();
2448 char xpath_arg[XPATH_MAXLEN];
2449 struct yang_data *data;
2450 struct isis_area *area = circuit->area;
2451
2452 notif_prep_instance_hdr(xpath, area, "default", arguments);
2453 notif_prepr_iface_hdr(xpath, circuit, arguments);
2454 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2455 data = yang_data_new(xpath_arg, raw_pdu);
2456 listnode_add(arguments, data);
2457
2458 nb_notification_send(xpath, arguments);
2459 }
2460
2461 /*
2462 * XPath:
2463 * /frr-isisd:adjacency-state-change
2464 */
2465 void isis_notif_adj_state_change(const struct isis_adjacency *adj,
2466 int new_state, const char *reason)
2467 {
2468 const char *xpath = "/frr-isisd:adjacency-state-change";
2469 struct list *arguments = yang_data_list_new();
2470 char xpath_arg[XPATH_MAXLEN];
2471 struct yang_data *data;
2472 struct isis_circuit *circuit = adj->circuit;
2473 struct isis_area *area = circuit->area;
2474 struct isis_dynhn *dyn = dynhn_find_by_id(adj->sysid);
2475
2476 notif_prep_instance_hdr(xpath, area, "default", arguments);
2477 notif_prepr_iface_hdr(xpath, circuit, arguments);
2478 if (dyn) {
2479 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor", xpath);
2480 data = yang_data_new_string(xpath_arg, dyn->hostname);
2481 listnode_add(arguments, data);
2482 }
2483 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
2484 data = yang_data_new_string(xpath_arg, sysid_print(adj->sysid));
2485 listnode_add(arguments, data);
2486
2487 snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
2488 switch (new_state) {
2489 case ISIS_ADJ_DOWN:
2490 data = yang_data_new_string(xpath_arg, "down");
2491 break;
2492 case ISIS_ADJ_UP:
2493 data = yang_data_new_string(xpath_arg, "up");
2494 break;
2495 case ISIS_ADJ_INITIALIZING:
2496 data = yang_data_new_string(xpath_arg, "init");
2497 break;
2498 default:
2499 data = yang_data_new_string(xpath_arg, "failed");
2500 }
2501 listnode_add(arguments, data);
2502 if (new_state == ISIS_ADJ_DOWN) {
2503 snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
2504 data = yang_data_new_string(xpath_arg, reason);
2505 listnode_add(arguments, data);
2506 }
2507
2508 nb_notification_send(xpath, arguments);
2509 }
2510
2511 /*
2512 * XPath:
2513 * /frr-isisd:rejected-adjacency
2514 */
2515 void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
2516 const char *reason, const char *raw_pdu)
2517 {
2518 const char *xpath = "/frr-isisd:rejected-adjacency";
2519 struct list *arguments = yang_data_list_new();
2520 char xpath_arg[XPATH_MAXLEN];
2521 struct yang_data *data;
2522 struct isis_area *area = circuit->area;
2523
2524 notif_prep_instance_hdr(xpath, area, "default", arguments);
2525 notif_prepr_iface_hdr(xpath, circuit, arguments);
2526 snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
2527 data = yang_data_new_string(xpath_arg, reason);
2528 listnode_add(arguments, data);
2529 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2530 data = yang_data_new(xpath_arg, raw_pdu);
2531 listnode_add(arguments, data);
2532
2533 nb_notification_send(xpath, arguments);
2534 }
2535
2536 /*
2537 * XPath:
2538 * /frr-isisd:area-mismatch
2539 */
2540 void isis_notif_area_mismatch(const struct isis_circuit *circuit,
2541 const char *raw_pdu)
2542 {
2543 const char *xpath = "/frr-isisd:area-mismatch";
2544 struct list *arguments = yang_data_list_new();
2545 char xpath_arg[XPATH_MAXLEN];
2546 struct yang_data *data;
2547 struct isis_area *area = circuit->area;
2548
2549 notif_prep_instance_hdr(xpath, area, "default", arguments);
2550 notif_prepr_iface_hdr(xpath, circuit, arguments);
2551 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2552 data = yang_data_new(xpath_arg, raw_pdu);
2553 listnode_add(arguments, data);
2554
2555 nb_notification_send(xpath, arguments);
2556 }
2557
2558 /*
2559 * XPath:
2560 * /frr-isisd:lsp-received
2561 */
2562 void isis_notif_lsp_received(const struct isis_circuit *circuit,
2563 const char *lsp_id, uint32_t seqno,
2564 uint32_t timestamp, const char *sys_id)
2565 {
2566 const char *xpath = "/frr-isisd:lsp-received";
2567 struct list *arguments = yang_data_list_new();
2568 char xpath_arg[XPATH_MAXLEN];
2569 struct yang_data *data;
2570 struct isis_area *area = circuit->area;
2571
2572 notif_prep_instance_hdr(xpath, area, "default", arguments);
2573 notif_prepr_iface_hdr(xpath, circuit, arguments);
2574 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2575 data = yang_data_new_string(xpath_arg, lsp_id);
2576 listnode_add(arguments, data);
2577 snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
2578 data = yang_data_new_uint32(xpath_arg, seqno);
2579 listnode_add(arguments, data);
2580 snprintf(xpath_arg, sizeof(xpath_arg), "%s/received-timestamp", xpath);
2581 data = yang_data_new_uint32(xpath_arg, timestamp);
2582 listnode_add(arguments, data);
2583 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
2584 data = yang_data_new_string(xpath_arg, sys_id);
2585 listnode_add(arguments, data);
2586
2587 nb_notification_send(xpath, arguments);
2588 }
2589
2590 /*
2591 * XPath:
2592 * /frr-isisd:lsp-generation
2593 */
2594 void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id,
2595 uint32_t seqno, uint32_t timestamp)
2596 {
2597 const char *xpath = "/frr-isisd:lsp-generation";
2598 struct list *arguments = yang_data_list_new();
2599 char xpath_arg[XPATH_MAXLEN];
2600 struct yang_data *data;
2601
2602 notif_prep_instance_hdr(xpath, area, "default", arguments);
2603 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2604 data = yang_data_new_string(xpath_arg, lsp_id);
2605 listnode_add(arguments, data);
2606 snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
2607 data = yang_data_new_uint32(xpath_arg, seqno);
2608 listnode_add(arguments, data);
2609 snprintf(xpath_arg, sizeof(xpath_arg), "%s/send-timestamp", xpath);
2610 data = yang_data_new_uint32(xpath_arg, timestamp);
2611 listnode_add(arguments, data);
2612
2613 nb_notification_send(xpath, arguments);
2614 }
2615
2616 /*
2617 * XPath:
2618 * /frr-isisd:id-len-mismatch
2619 */
2620 void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
2621 uint8_t rcv_id_len, const char *raw_pdu)
2622 {
2623 const char *xpath = "/frr-isisd:id-len-mismatch";
2624 struct list *arguments = yang_data_list_new();
2625 char xpath_arg[XPATH_MAXLEN];
2626 struct yang_data *data;
2627 struct isis_area *area = circuit->area;
2628
2629 notif_prep_instance_hdr(xpath, area, "default", arguments);
2630 notif_prepr_iface_hdr(xpath, circuit, arguments);
2631 snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-field-len", xpath);
2632 data = yang_data_new_uint8(xpath_arg, rcv_id_len);
2633 listnode_add(arguments, data);
2634 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2635 data = yang_data_new(xpath_arg, raw_pdu);
2636 listnode_add(arguments, data);
2637
2638 nb_notification_send(xpath, arguments);
2639 }
2640
2641 /*
2642 * XPath:
2643 * /frr-isisd:version-skew
2644 */
2645 void isis_notif_version_skew(const struct isis_circuit *circuit,
2646 uint8_t version, const char *raw_pdu)
2647 {
2648 const char *xpath = "/frr-isisd:version-skew";
2649 struct list *arguments = yang_data_list_new();
2650 char xpath_arg[XPATH_MAXLEN];
2651 struct yang_data *data;
2652 struct isis_area *area = circuit->area;
2653
2654 notif_prep_instance_hdr(xpath, area, "default", arguments);
2655 notif_prepr_iface_hdr(xpath, circuit, arguments);
2656 snprintf(xpath_arg, sizeof(xpath_arg), "%s/protocol-version", xpath);
2657 data = yang_data_new_uint8(xpath_arg, version);
2658 listnode_add(arguments, data);
2659 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2660 data = yang_data_new(xpath_arg, raw_pdu);
2661 listnode_add(arguments, data);
2662
2663 nb_notification_send(xpath, arguments);
2664 }
2665
2666 /*
2667 * XPath:
2668 * /frr-isisd:lsp-error-detected
2669 */
2670 void isis_notif_lsp_error(const struct isis_circuit *circuit,
2671 const char *lsp_id, const char *raw_pdu,
2672 __attribute__((unused)) uint32_t offset,
2673 __attribute__((unused)) uint8_t tlv_type)
2674 {
2675 const char *xpath = "/frr-isisd:lsp-error-detected";
2676 struct list *arguments = yang_data_list_new();
2677 char xpath_arg[XPATH_MAXLEN];
2678 struct yang_data *data;
2679 struct isis_area *area = circuit->area;
2680
2681 notif_prep_instance_hdr(xpath, area, "default", arguments);
2682 notif_prepr_iface_hdr(xpath, circuit, arguments);
2683 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2684 data = yang_data_new_string(xpath_arg, lsp_id);
2685 listnode_add(arguments, data);
2686 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2687 data = yang_data_new(xpath_arg, raw_pdu);
2688 listnode_add(arguments, data);
2689 /* ignore offset and tlv_type which cannot be set properly */
2690
2691 nb_notification_send(xpath, arguments);
2692 }
2693
2694 /*
2695 * XPath:
2696 * /frr-isisd:sequence-number-skipped
2697 */
2698 void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
2699 const char *lsp_id)
2700 {
2701 const char *xpath = "/frr-isisd:sequence-number-skipped";
2702 struct list *arguments = yang_data_list_new();
2703 char xpath_arg[XPATH_MAXLEN];
2704 struct yang_data *data;
2705 struct isis_area *area = circuit->area;
2706
2707 notif_prep_instance_hdr(xpath, area, "default", arguments);
2708 notif_prepr_iface_hdr(xpath, circuit, arguments);
2709 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2710 data = yang_data_new_string(xpath_arg, lsp_id);
2711 listnode_add(arguments, data);
2712
2713 nb_notification_send(xpath, arguments);
2714 }
2715
2716 /*
2717 * XPath:
2718 * /frr-isisd:own-lsp-purge
2719 */
2720 void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
2721 const char *lsp_id)
2722 {
2723 const char *xpath = "/frr-isisd:own-lsp-purge";
2724 struct list *arguments = yang_data_list_new();
2725 char xpath_arg[XPATH_MAXLEN];
2726 struct yang_data *data;
2727 struct isis_area *area = circuit->area;
2728
2729 notif_prep_instance_hdr(xpath, area, "default", arguments);
2730 notif_prepr_iface_hdr(xpath, circuit, arguments);
2731 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2732 data = yang_data_new_string(xpath_arg, lsp_id);
2733 listnode_add(arguments, data);
2734
2735 nb_notification_send(xpath, arguments);
2736 }
2737
2738 /* clang-format off */
2739 const struct frr_yang_module_info frr_isisd_info = {
2740 .name = "frr-isisd",
2741 .nodes = {
2742 {
2743 .xpath = "/frr-isisd:isis/instance",
2744 .cbs.create = isis_instance_create,
2745 .cbs.destroy = isis_instance_destroy,
2746 .cbs.cli_show = cli_show_router_isis,
2747 .priority = NB_DFLT_PRIORITY - 1,
2748 },
2749 {
2750 .xpath = "/frr-isisd:isis/instance/is-type",
2751 .cbs.modify = isis_instance_is_type_modify,
2752 .cbs.cli_show = cli_show_isis_is_type,
2753 },
2754 {
2755 .xpath = "/frr-isisd:isis/instance/area-address",
2756 .cbs.create = isis_instance_area_address_create,
2757 .cbs.destroy = isis_instance_area_address_destroy,
2758 .cbs.cli_show = cli_show_isis_area_address,
2759 },
2760 {
2761 .xpath = "/frr-isisd:isis/instance/dynamic-hostname",
2762 .cbs.modify = isis_instance_dynamic_hostname_modify,
2763 .cbs.cli_show = cli_show_isis_dynamic_hostname,
2764 },
2765 {
2766 .xpath = "/frr-isisd:isis/instance/attached",
2767 .cbs.modify = isis_instance_attached_modify,
2768 .cbs.cli_show = cli_show_isis_attached,
2769 },
2770 {
2771 .xpath = "/frr-isisd:isis/instance/overload",
2772 .cbs.modify = isis_instance_overload_modify,
2773 .cbs.cli_show = cli_show_isis_overload,
2774 },
2775 {
2776 .xpath = "/frr-isisd:isis/instance/metric-style",
2777 .cbs.modify = isis_instance_metric_style_modify,
2778 .cbs.cli_show = cli_show_isis_metric_style,
2779 },
2780 {
2781 .xpath = "/frr-isisd:isis/instance/purge-originator",
2782 .cbs.modify = isis_instance_purge_originator_modify,
2783 .cbs.cli_show = cli_show_isis_purge_origin,
2784 },
2785 {
2786 .xpath = "/frr-isisd:isis/instance/lsp/mtu",
2787 .cbs.modify = isis_instance_lsp_mtu_modify,
2788 .cbs.cli_show = cli_show_isis_lsp_mtu,
2789 },
2790 {
2791 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval",
2792 .cbs.cli_show = cli_show_isis_lsp_ref_interval,
2793 },
2794 {
2795 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-1",
2796 .cbs.modify = isis_instance_lsp_refresh_interval_level_1_modify,
2797 },
2798 {
2799 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-2",
2800 .cbs.modify = isis_instance_lsp_refresh_interval_level_2_modify,
2801 },
2802 {
2803 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime",
2804 .cbs.cli_show = cli_show_isis_lsp_max_lifetime,
2805 },
2806 {
2807 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1",
2808 .cbs.modify = isis_instance_lsp_maximum_lifetime_level_1_modify,
2809 },
2810 {
2811 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2",
2812 .cbs.modify = isis_instance_lsp_maximum_lifetime_level_2_modify,
2813 },
2814 {
2815 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval",
2816 .cbs.cli_show = cli_show_isis_lsp_gen_interval,
2817 },
2818 {
2819 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-1",
2820 .cbs.modify = isis_instance_lsp_generation_interval_level_1_modify,
2821 },
2822 {
2823 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-2",
2824 .cbs.modify = isis_instance_lsp_generation_interval_level_2_modify,
2825 },
2826 {
2827 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay",
2828 .cbs.create = isis_instance_spf_ietf_backoff_delay_create,
2829 .cbs.destroy = isis_instance_spf_ietf_backoff_delay_destroy,
2830 .cbs.apply_finish = ietf_backoff_delay_apply_finish,
2831 .cbs.cli_show = cli_show_isis_spf_ietf_backoff,
2832 },
2833 {
2834 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay",
2835 .cbs.modify = isis_instance_spf_ietf_backoff_delay_init_delay_modify,
2836 },
2837 {
2838 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay",
2839 .cbs.modify = isis_instance_spf_ietf_backoff_delay_short_delay_modify,
2840 },
2841 {
2842 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay",
2843 .cbs.modify = isis_instance_spf_ietf_backoff_delay_long_delay_modify,
2844 },
2845 {
2846 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down",
2847 .cbs.modify = isis_instance_spf_ietf_backoff_delay_hold_down_modify,
2848 },
2849 {
2850 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn",
2851 .cbs.modify = isis_instance_spf_ietf_backoff_delay_time_to_learn_modify,
2852 },
2853 {
2854 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval",
2855 .cbs.cli_show = cli_show_isis_spf_min_interval,
2856 },
2857 {
2858 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-1",
2859 .cbs.modify = isis_instance_spf_minimum_interval_level_1_modify,
2860 },
2861 {
2862 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-2",
2863 .cbs.modify = isis_instance_spf_minimum_interval_level_2_modify,
2864 },
2865 {
2866 .xpath = "/frr-isisd:isis/instance/area-password",
2867 .cbs.create = isis_instance_area_password_create,
2868 .cbs.destroy = isis_instance_area_password_destroy,
2869 .cbs.apply_finish = area_password_apply_finish,
2870 .cbs.cli_show = cli_show_isis_area_pwd,
2871 },
2872 {
2873 .xpath = "/frr-isisd:isis/instance/area-password/password",
2874 .cbs.modify = isis_instance_area_password_password_modify,
2875 },
2876 {
2877 .xpath = "/frr-isisd:isis/instance/area-password/password-type",
2878 .cbs.modify = isis_instance_area_password_password_type_modify,
2879 },
2880 {
2881 .xpath = "/frr-isisd:isis/instance/area-password/authenticate-snp",
2882 .cbs.modify = isis_instance_area_password_authenticate_snp_modify,
2883 },
2884 {
2885 .xpath = "/frr-isisd:isis/instance/domain-password",
2886 .cbs.create = isis_instance_domain_password_create,
2887 .cbs.destroy = isis_instance_domain_password_destroy,
2888 .cbs.apply_finish = domain_password_apply_finish,
2889 .cbs.cli_show = cli_show_isis_domain_pwd,
2890 },
2891 {
2892 .xpath = "/frr-isisd:isis/instance/domain-password/password",
2893 .cbs.modify = isis_instance_domain_password_password_modify,
2894 },
2895 {
2896 .xpath = "/frr-isisd:isis/instance/domain-password/password-type",
2897 .cbs.modify = isis_instance_domain_password_password_type_modify,
2898 },
2899 {
2900 .xpath = "/frr-isisd:isis/instance/domain-password/authenticate-snp",
2901 .cbs.modify = isis_instance_domain_password_authenticate_snp_modify,
2902 },
2903 {
2904 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
2905 .cbs.create = isis_instance_default_information_originate_ipv4_create,
2906 .cbs.destroy = isis_instance_default_information_originate_ipv4_destroy,
2907 .cbs.apply_finish = default_info_origin_ipv4_apply_finish,
2908 .cbs.cli_show = cli_show_isis_def_origin_ipv4,
2909 },
2910 {
2911 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
2912 .cbs.modify = isis_instance_default_information_originate_ipv4_always_modify,
2913 },
2914 {
2915 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/route-map",
2916 .cbs.modify = isis_instance_default_information_originate_ipv4_route_map_modify,
2917 .cbs.destroy = isis_instance_default_information_originate_ipv4_route_map_destroy,
2918 },
2919 {
2920 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/metric",
2921 .cbs.modify = isis_instance_default_information_originate_ipv4_metric_modify,
2922 },
2923 {
2924 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
2925 .cbs.create = isis_instance_default_information_originate_ipv6_create,
2926 .cbs.destroy = isis_instance_default_information_originate_ipv6_destroy,
2927 .cbs.apply_finish = default_info_origin_ipv6_apply_finish,
2928 .cbs.cli_show = cli_show_isis_def_origin_ipv6,
2929 },
2930 {
2931 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
2932 .cbs.modify = isis_instance_default_information_originate_ipv6_always_modify,
2933 },
2934 {
2935 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/route-map",
2936 .cbs.modify = isis_instance_default_information_originate_ipv6_route_map_modify,
2937 .cbs.destroy = isis_instance_default_information_originate_ipv6_route_map_destroy,
2938 },
2939 {
2940 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/metric",
2941 .cbs.modify = isis_instance_default_information_originate_ipv6_metric_modify,
2942 },
2943 {
2944 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4",
2945 .cbs.create = isis_instance_redistribute_ipv4_create,
2946 .cbs.destroy = isis_instance_redistribute_ipv4_destroy,
2947 .cbs.apply_finish = redistribute_ipv4_apply_finish,
2948 .cbs.cli_show = cli_show_isis_redistribute_ipv4,
2949 },
2950 {
2951 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/route-map",
2952 .cbs.modify = isis_instance_redistribute_ipv4_route_map_modify,
2953 .cbs.destroy = isis_instance_redistribute_ipv4_route_map_destroy,
2954 },
2955 {
2956 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",
2957 .cbs.modify = isis_instance_redistribute_ipv4_metric_modify,
2958 },
2959 {
2960 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6",
2961 .cbs.create = isis_instance_redistribute_ipv6_create,
2962 .cbs.destroy = isis_instance_redistribute_ipv6_destroy,
2963 .cbs.apply_finish = redistribute_ipv6_apply_finish,
2964 .cbs.cli_show = cli_show_isis_redistribute_ipv6,
2965 },
2966 {
2967 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/route-map",
2968 .cbs.modify = isis_instance_redistribute_ipv6_route_map_modify,
2969 .cbs.destroy = isis_instance_redistribute_ipv6_route_map_destroy,
2970 },
2971 {
2972 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",
2973 .cbs.modify = isis_instance_redistribute_ipv6_metric_modify,
2974 },
2975 {
2976 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast",
2977 .cbs.create = isis_instance_multi_topology_ipv4_multicast_create,
2978 .cbs.destroy = isis_instance_multi_topology_ipv4_multicast_destroy,
2979 .cbs.cli_show = cli_show_isis_mt_ipv4_multicast,
2980 },
2981 {
2982 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload",
2983 .cbs.modify = isis_instance_multi_topology_ipv4_multicast_overload_modify,
2984 },
2985 {
2986 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management",
2987 .cbs.create = isis_instance_multi_topology_ipv4_management_create,
2988 .cbs.destroy = isis_instance_multi_topology_ipv4_management_destroy,
2989 .cbs.cli_show = cli_show_isis_mt_ipv4_mgmt,
2990 },
2991 {
2992 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management/overload",
2993 .cbs.modify = isis_instance_multi_topology_ipv4_management_overload_modify,
2994 },
2995 {
2996 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast",
2997 .cbs.create = isis_instance_multi_topology_ipv6_unicast_create,
2998 .cbs.destroy = isis_instance_multi_topology_ipv6_unicast_destroy,
2999 .cbs.cli_show = cli_show_isis_mt_ipv6_unicast,
3000 },
3001 {
3002 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload",
3003 .cbs.modify = isis_instance_multi_topology_ipv6_unicast_overload_modify,
3004 },
3005 {
3006 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast",
3007 .cbs.create = isis_instance_multi_topology_ipv6_multicast_create,
3008 .cbs.destroy = isis_instance_multi_topology_ipv6_multicast_destroy,
3009 .cbs.cli_show = cli_show_isis_mt_ipv6_multicast,
3010 },
3011 {
3012 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload",
3013 .cbs.modify = isis_instance_multi_topology_ipv6_multicast_overload_modify,
3014 },
3015 {
3016 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management",
3017 .cbs.create = isis_instance_multi_topology_ipv6_management_create,
3018 .cbs.destroy = isis_instance_multi_topology_ipv6_management_destroy,
3019 .cbs.cli_show = cli_show_isis_mt_ipv6_mgmt,
3020 },
3021 {
3022 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management/overload",
3023 .cbs.modify = isis_instance_multi_topology_ipv6_management_overload_modify,
3024 },
3025 {
3026 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc",
3027 .cbs.create = isis_instance_multi_topology_ipv6_dstsrc_create,
3028 .cbs.destroy = isis_instance_multi_topology_ipv6_dstsrc_destroy,
3029 .cbs.cli_show = cli_show_isis_mt_ipv6_dstsrc,
3030 },
3031 {
3032 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload",
3033 .cbs.modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify,
3034 },
3035 {
3036 .xpath = "/frr-isisd:isis/instance/log-adjacency-changes",
3037 .cbs.modify = isis_instance_log_adjacency_changes_modify,
3038 .cbs.cli_show = cli_show_isis_log_adjacency,
3039 },
3040 {
3041 .xpath = "/frr-isisd:isis/instance/mpls-te",
3042 .cbs.create = isis_instance_mpls_te_create,
3043 .cbs.destroy = isis_instance_mpls_te_destroy,
3044 .cbs.cli_show = cli_show_isis_mpls_te,
3045 },
3046 {
3047 .xpath = "/frr-isisd:isis/instance/mpls-te/router-address",
3048 .cbs.modify = isis_instance_mpls_te_router_address_modify,
3049 .cbs.destroy = isis_instance_mpls_te_router_address_destroy,
3050 .cbs.cli_show = cli_show_isis_mpls_te_router_addr,
3051 },
3052 {
3053 .xpath = "/frr-interface:lib/interface/frr-isisd:isis",
3054 .cbs.create = lib_interface_isis_create,
3055 .cbs.destroy = lib_interface_isis_destroy,
3056 },
3057 {
3058 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/area-tag",
3059 .cbs.modify = lib_interface_isis_area_tag_modify,
3060 },
3061 {
3062 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type",
3063 .cbs.modify = lib_interface_isis_circuit_type_modify,
3064 .cbs.cli_show = cli_show_ip_isis_circ_type,
3065 },
3066 {
3067 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing",
3068 .cbs.modify = lib_interface_isis_ipv4_routing_modify,
3069 .cbs.cli_show = cli_show_ip_isis_ipv4,
3070 },
3071 {
3072 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing",
3073 .cbs.modify = lib_interface_isis_ipv6_routing_modify,
3074 .cbs.cli_show = cli_show_ip_isis_ipv6,
3075 },
3076 {
3077 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval",
3078 .cbs.cli_show = cli_show_ip_isis_csnp_interval,
3079 },
3080 {
3081 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1",
3082 .cbs.modify = lib_interface_isis_csnp_interval_level_1_modify,
3083 },
3084 {
3085 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2",
3086 .cbs.modify = lib_interface_isis_csnp_interval_level_2_modify,
3087 },
3088 {
3089 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval",
3090 .cbs.cli_show = cli_show_ip_isis_psnp_interval,
3091 },
3092 {
3093 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1",
3094 .cbs.modify = lib_interface_isis_psnp_interval_level_1_modify,
3095 },
3096 {
3097 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2",
3098 .cbs.modify = lib_interface_isis_psnp_interval_level_2_modify,
3099 },
3100 {
3101 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/padding",
3102 .cbs.modify = lib_interface_isis_hello_padding_modify,
3103 .cbs.cli_show = cli_show_ip_isis_hello_padding,
3104 },
3105 {
3106 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval",
3107 .cbs.cli_show = cli_show_ip_isis_hello_interval,
3108 },
3109 {
3110 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1",
3111 .cbs.modify = lib_interface_isis_hello_interval_level_1_modify,
3112 },
3113 {
3114 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2",
3115 .cbs.modify = lib_interface_isis_hello_interval_level_2_modify,
3116 },
3117 {
3118 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier",
3119 .cbs.cli_show = cli_show_ip_isis_hello_multi,
3120 },
3121 {
3122 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1",
3123 .cbs.modify = lib_interface_isis_hello_multiplier_level_1_modify,
3124 },
3125 {
3126 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2",
3127 .cbs.modify = lib_interface_isis_hello_multiplier_level_2_modify,
3128 },
3129 {
3130 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric",
3131 .cbs.cli_show = cli_show_ip_isis_metric,
3132 },
3133 {
3134 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1",
3135 .cbs.modify = lib_interface_isis_metric_level_1_modify,
3136 },
3137 {
3138 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2",
3139 .cbs.modify = lib_interface_isis_metric_level_2_modify,
3140 },
3141 {
3142 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority",
3143 .cbs.cli_show = cli_show_ip_isis_priority,
3144 },
3145 {
3146 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1",
3147 .cbs.modify = lib_interface_isis_priority_level_1_modify,
3148 },
3149 {
3150 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2",
3151 .cbs.modify = lib_interface_isis_priority_level_2_modify,
3152 },
3153 {
3154 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/network-type",
3155 .cbs.modify = lib_interface_isis_network_type_modify,
3156 .cbs.cli_show = cli_show_ip_isis_network_type,
3157 },
3158 {
3159 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/passive",
3160 .cbs.modify = lib_interface_isis_passive_modify,
3161 .cbs.cli_show = cli_show_ip_isis_passive,
3162 },
3163 {
3164 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password",
3165 .cbs.create = lib_interface_isis_password_create,
3166 .cbs.destroy = lib_interface_isis_password_destroy,
3167 .cbs.cli_show = cli_show_ip_isis_password,
3168 },
3169 {
3170 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password",
3171 .cbs.modify = lib_interface_isis_password_password_modify,
3172 },
3173 {
3174 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password-type",
3175 .cbs.modify = lib_interface_isis_password_password_type_modify,
3176 },
3177 {
3178 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake",
3179 .cbs.modify = lib_interface_isis_disable_three_way_handshake_modify,
3180 .cbs.cli_show = cli_show_ip_isis_threeway_shake,
3181 },
3182 {
3183 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast",
3184 .cbs.modify = lib_interface_isis_multi_topology_ipv4_unicast_modify,
3185 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_unicast,
3186 },
3187 {
3188 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast",
3189 .cbs.modify = lib_interface_isis_multi_topology_ipv4_multicast_modify,
3190 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_multicast,
3191 },
3192 {
3193 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management",
3194 .cbs.modify = lib_interface_isis_multi_topology_ipv4_management_modify,
3195 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_mgmt,
3196 },
3197 {
3198 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast",
3199 .cbs.modify = lib_interface_isis_multi_topology_ipv6_unicast_modify,
3200 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_unicast,
3201 },
3202 {
3203 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast",
3204 .cbs.modify = lib_interface_isis_multi_topology_ipv6_multicast_modify,
3205 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_multicast,
3206 },
3207 {
3208 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management",
3209 .cbs.modify = lib_interface_isis_multi_topology_ipv6_management_modify,
3210 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_mgmt,
3211 },
3212 {
3213 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc",
3214 .cbs.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
3215 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_dstsrc,
3216 },
3217 {
3218 .xpath = NULL,
3219 },
3220 }
3221 };