]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_northbound.c
isisd: replace dict_* with DECLARE_RBTREE
[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 yang_dnode_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 const char *area_tag;
78
79 if (event != NB_EV_APPLY)
80 return NB_OK;
81
82 area_tag = yang_dnode_get_string(dnode, "./area-tag");
83 isis_area_destroy(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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, 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 = yang_dnode_get_entry(dnode, true);
1361 area->log_adj_changes = log ? 1 : 0;
1362
1363 return NB_OK;
1364 }
1365
1366 /*
1367 * XPath: /frr-isisd:isis/mpls-te
1368 */
1369 static int isis_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_circuit *circuit;
1375
1376 if (event != NB_EV_APPLY)
1377 return NB_OK;
1378
1379 isisMplsTE.status = enable;
1380
1381 /*
1382 * Following code is intended to handle two cases;
1383 *
1384 * 1) MPLS-TE was disabled at startup time, but now become enabled.
1385 * In this case, we must enable MPLS-TE Circuit regarding interface
1386 * MPLS_TE flag
1387 * 2) MPLS-TE was once enabled then disabled, and now enabled again.
1388 */
1389 for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
1390 if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
1391 continue;
1392
1393 if ((circuit->mtc->status == disable)
1394 && HAS_LINK_PARAMS(circuit->interface))
1395 circuit->mtc->status = enable;
1396 else
1397 continue;
1398
1399 /* Reoriginate STD_TE & GMPLS circuits */
1400 if (circuit->area)
1401 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1402 0);
1403 }
1404
1405 return NB_OK;
1406 }
1407
1408 static int isis_mpls_te_destroy(enum nb_event event,
1409 const struct lyd_node *dnode)
1410 {
1411 struct listnode *node;
1412 struct isis_circuit *circuit;
1413
1414 if (event != NB_EV_APPLY)
1415 return NB_OK;
1416
1417 isisMplsTE.status = disable;
1418
1419 /* Flush LSP if circuit engage */
1420 for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
1421 if (circuit->mtc == NULL || (circuit->mtc->status == disable))
1422 continue;
1423
1424 /* disable MPLS_TE Circuit */
1425 circuit->mtc->status = disable;
1426
1427 /* Re-originate circuit without STD_TE & GMPLS parameters */
1428 if (circuit->area)
1429 lsp_regenerate_schedule(circuit->area, circuit->is_type,
1430 0);
1431 }
1432
1433 return NB_OK;
1434 }
1435
1436 /*
1437 * XPath: /frr-isisd:isis/mpls-te/router-address
1438 */
1439 static int isis_mpls_te_router_address_modify(enum nb_event event,
1440 const struct lyd_node *dnode,
1441 union nb_resource *resource)
1442 {
1443 struct in_addr value;
1444 struct listnode *node;
1445 struct isis_area *area;
1446
1447 if (event != NB_EV_APPLY)
1448 return NB_OK;
1449
1450 yang_dnode_get_ipv4(&value, dnode, NULL);
1451 isisMplsTE.router_id.s_addr = value.s_addr;
1452 /* only proceed if MPLS-TE is enabled */
1453 if (isisMplsTE.status == disable)
1454 return NB_OK;
1455
1456 /* Update main Router ID in isis global structure */
1457 isis->router_id = value.s_addr;
1458 /* And re-schedule LSP update */
1459 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
1460 if (listcount(area->area_addrs) > 0)
1461 lsp_regenerate_schedule(area, area->is_type, 0);
1462
1463 return NB_OK;
1464 }
1465
1466 static int isis_mpls_te_router_address_destroy(enum nb_event event,
1467 const struct lyd_node *dnode)
1468 {
1469 struct listnode *node;
1470 struct isis_area *area;
1471
1472 if (event != NB_EV_APPLY)
1473 return NB_OK;
1474
1475 isisMplsTE.router_id.s_addr = INADDR_ANY;
1476 /* only proceed if MPLS-TE is enabled */
1477 if (isisMplsTE.status == disable)
1478 return NB_OK;
1479
1480 /* Update main Router ID in isis global structure */
1481 isis->router_id = 0;
1482 /* And re-schedule LSP update */
1483 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
1484 if (listcount(area->area_addrs) > 0)
1485 lsp_regenerate_schedule(area, area->is_type, 0);
1486
1487 return NB_OK;
1488 }
1489
1490 /*
1491 * XPath: /frr-interface:lib/interface/frr-isisd:isis
1492 */
1493 static int lib_interface_isis_create(enum nb_event event,
1494 const struct lyd_node *dnode,
1495 union nb_resource *resource)
1496 {
1497 struct isis_area *area;
1498 struct interface *ifp;
1499 struct isis_circuit *circuit;
1500 const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
1501
1502 if (event != NB_EV_APPLY)
1503 return NB_OK;
1504
1505 area = isis_area_lookup(area_tag);
1506 /* The area should have already be created. We are
1507 * setting the priority of the global isis area creation
1508 * slightly lower, so it should be executed first, but I
1509 * cannot rely on that so here I have to check.
1510 */
1511 if (!area) {
1512 flog_err(
1513 EC_LIB_NB_CB_CONFIG_APPLY,
1514 "%s: attempt to create circuit for area %s before the area has been created",
1515 __func__, area_tag);
1516 abort();
1517 }
1518
1519 ifp = yang_dnode_get_entry(dnode, true);
1520 circuit = isis_circuit_create(area, ifp);
1521 assert(circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
1522 yang_dnode_set_entry(dnode, circuit);
1523
1524 return NB_OK;
1525 }
1526
1527 static int lib_interface_isis_destroy(enum nb_event event,
1528 const struct lyd_node *dnode)
1529 {
1530 struct isis_circuit *circuit;
1531
1532 if (event != NB_EV_APPLY)
1533 return NB_OK;
1534
1535 circuit = yang_dnode_get_entry(dnode, true);
1536 if (!circuit)
1537 return NB_ERR_INCONSISTENCY;
1538 /* delete circuit through csm changes */
1539 switch (circuit->state) {
1540 case C_STATE_UP:
1541 isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
1542 circuit->interface);
1543 isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
1544 break;
1545 case C_STATE_CONF:
1546 isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
1547 break;
1548 case C_STATE_INIT:
1549 isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
1550 circuit->interface);
1551 break;
1552 }
1553
1554 return NB_OK;
1555 }
1556
1557 /*
1558 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1559 */
1560 static int lib_interface_isis_area_tag_modify(enum nb_event event,
1561 const struct lyd_node *dnode,
1562 union nb_resource *resource)
1563 {
1564 struct isis_circuit *circuit;
1565 struct interface *ifp;
1566 struct vrf *vrf;
1567 const char *area_tag, *ifname, *vrfname;
1568
1569 if (event == NB_EV_VALIDATE) {
1570 /* libyang doesn't like relative paths across module boundaries
1571 */
1572 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1573 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1574 vrf = vrf_lookup_by_name(vrfname);
1575 assert(vrf);
1576 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1577 if (!ifp)
1578 return NB_OK;
1579 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1580 area_tag = yang_dnode_get_string(dnode, NULL);
1581 if (circuit && circuit->area && circuit->area->area_tag
1582 && strcmp(circuit->area->area_tag, area_tag)) {
1583 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1584 "ISIS circuit is already defined on %s",
1585 circuit->area->area_tag);
1586 return NB_ERR_VALIDATION;
1587 }
1588 }
1589
1590 return NB_OK;
1591 }
1592
1593 /*
1594 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1595 */
1596 static int lib_interface_isis_circuit_type_modify(enum nb_event event,
1597 const struct lyd_node *dnode,
1598 union nb_resource *resource)
1599 {
1600 int circ_type = yang_dnode_get_enum(dnode, NULL);
1601 struct isis_circuit *circuit;
1602 struct interface *ifp;
1603 struct vrf *vrf;
1604 const char *ifname, *vrfname;
1605
1606 switch (event) {
1607 case NB_EV_VALIDATE:
1608 /* libyang doesn't like relative paths across module boundaries
1609 */
1610 ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
1611 vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
1612 vrf = vrf_lookup_by_name(vrfname);
1613 assert(vrf);
1614 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1615 if (!ifp)
1616 break;
1617 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1618 if (circuit && circuit->state == C_STATE_UP
1619 && circuit->area->is_type != IS_LEVEL_1_AND_2
1620 && circuit->area->is_type != circ_type) {
1621 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
1622 "Invalid circuit level for area %s",
1623 circuit->area->area_tag);
1624 return NB_ERR_VALIDATION;
1625 }
1626 break;
1627 case NB_EV_PREPARE:
1628 case NB_EV_ABORT:
1629 break;
1630 case NB_EV_APPLY:
1631 circuit = yang_dnode_get_entry(dnode, true);
1632 isis_circuit_is_type_set(circuit, circ_type);
1633 break;
1634 }
1635
1636 return NB_OK;
1637 }
1638
1639 /*
1640 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1641 */
1642 static int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
1643 const struct lyd_node *dnode,
1644 union nb_resource *resource)
1645 {
1646 bool ipv4, ipv6;
1647 struct isis_circuit *circuit;
1648
1649 if (event != NB_EV_APPLY)
1650 return NB_OK;
1651
1652 circuit = yang_dnode_get_entry(dnode, true);
1653 ipv4 = yang_dnode_get_bool(dnode, NULL);
1654 ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
1655 isis_circuit_af_set(circuit, ipv4, ipv6);
1656
1657 return NB_OK;
1658 }
1659
1660 /*
1661 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1662 */
1663 static int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
1664 const struct lyd_node *dnode,
1665 union nb_resource *resource)
1666 {
1667 bool ipv4, ipv6;
1668 struct isis_circuit *circuit;
1669
1670 if (event != NB_EV_APPLY)
1671 return NB_OK;
1672
1673 circuit = yang_dnode_get_entry(dnode, true);
1674 ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
1675 ipv6 = yang_dnode_get_bool(dnode, NULL);
1676 isis_circuit_af_set(circuit, ipv4, ipv6);
1677
1678 return NB_OK;
1679 }
1680
1681 /*
1682 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1683 */
1684 static int
1685 lib_interface_isis_csnp_interval_level_1_modify(enum nb_event event,
1686 const struct lyd_node *dnode,
1687 union nb_resource *resource)
1688 {
1689 struct isis_circuit *circuit;
1690
1691 if (event != NB_EV_APPLY)
1692 return NB_OK;
1693
1694 circuit = yang_dnode_get_entry(dnode, true);
1695 circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1696
1697 return NB_OK;
1698 }
1699
1700 /*
1701 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1702 */
1703 static int
1704 lib_interface_isis_csnp_interval_level_2_modify(enum nb_event event,
1705 const struct lyd_node *dnode,
1706 union nb_resource *resource)
1707 {
1708 struct isis_circuit *circuit;
1709
1710 if (event != NB_EV_APPLY)
1711 return NB_OK;
1712
1713 circuit = yang_dnode_get_entry(dnode, true);
1714 circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1715
1716 return NB_OK;
1717 }
1718
1719 /*
1720 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1721 */
1722 static int
1723 lib_interface_isis_psnp_interval_level_1_modify(enum nb_event event,
1724 const struct lyd_node *dnode,
1725 union nb_resource *resource)
1726 {
1727 struct isis_circuit *circuit;
1728
1729 if (event != NB_EV_APPLY)
1730 return NB_OK;
1731
1732 circuit = yang_dnode_get_entry(dnode, true);
1733 circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
1734
1735 return NB_OK;
1736 }
1737
1738 /*
1739 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1740 */
1741 static int
1742 lib_interface_isis_psnp_interval_level_2_modify(enum nb_event event,
1743 const struct lyd_node *dnode,
1744 union nb_resource *resource)
1745 {
1746 struct isis_circuit *circuit;
1747
1748 if (event != NB_EV_APPLY)
1749 return NB_OK;
1750
1751 circuit = yang_dnode_get_entry(dnode, true);
1752 circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
1753
1754 return NB_OK;
1755 }
1756
1757 /*
1758 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1759 */
1760 static int lib_interface_isis_hello_padding_modify(enum nb_event event,
1761 const struct lyd_node *dnode,
1762 union nb_resource *resource)
1763 {
1764 struct isis_circuit *circuit;
1765
1766 if (event != NB_EV_APPLY)
1767 return NB_OK;
1768
1769 circuit = yang_dnode_get_entry(dnode, true);
1770 circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL);
1771
1772 return NB_OK;
1773 }
1774
1775 /*
1776 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1777 */
1778 static int
1779 lib_interface_isis_hello_interval_level_1_modify(enum nb_event event,
1780 const struct lyd_node *dnode,
1781 union nb_resource *resource)
1782 {
1783 struct isis_circuit *circuit;
1784 uint32_t interval;
1785
1786 if (event != NB_EV_APPLY)
1787 return NB_OK;
1788
1789 circuit = yang_dnode_get_entry(dnode, true);
1790 interval = yang_dnode_get_uint32(dnode, NULL);
1791 circuit->hello_interval[0] = interval;
1792
1793 return NB_OK;
1794 }
1795
1796 /*
1797 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1798 */
1799 static int
1800 lib_interface_isis_hello_interval_level_2_modify(enum nb_event event,
1801 const struct lyd_node *dnode,
1802 union nb_resource *resource)
1803 {
1804 struct isis_circuit *circuit;
1805 uint32_t interval;
1806
1807 if (event != NB_EV_APPLY)
1808 return NB_OK;
1809
1810 circuit = yang_dnode_get_entry(dnode, true);
1811 interval = yang_dnode_get_uint32(dnode, NULL);
1812 circuit->hello_interval[1] = interval;
1813
1814 return NB_OK;
1815 }
1816
1817 /*
1818 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
1819 */
1820 static int
1821 lib_interface_isis_hello_multiplier_level_1_modify(enum nb_event event,
1822 const struct lyd_node *dnode,
1823 union nb_resource *resource)
1824 {
1825 struct isis_circuit *circuit;
1826 uint16_t multi;
1827
1828 if (event != NB_EV_APPLY)
1829 return NB_OK;
1830
1831 circuit = yang_dnode_get_entry(dnode, true);
1832 multi = yang_dnode_get_uint16(dnode, NULL);
1833 circuit->hello_multiplier[0] = multi;
1834
1835 return NB_OK;
1836 }
1837
1838 /*
1839 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1840 */
1841 static int
1842 lib_interface_isis_hello_multiplier_level_2_modify(enum nb_event event,
1843 const struct lyd_node *dnode,
1844 union nb_resource *resource)
1845 {
1846 struct isis_circuit *circuit;
1847 uint16_t multi;
1848
1849 if (event != NB_EV_APPLY)
1850 return NB_OK;
1851
1852 circuit = yang_dnode_get_entry(dnode, true);
1853 multi = yang_dnode_get_uint16(dnode, NULL);
1854 circuit->hello_multiplier[1] = multi;
1855
1856 return NB_OK;
1857 }
1858
1859 /*
1860 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1861 */
1862 static int
1863 lib_interface_isis_metric_level_1_modify(enum nb_event event,
1864 const struct lyd_node *dnode,
1865 union nb_resource *resource)
1866 {
1867 struct isis_circuit *circuit;
1868 unsigned int met;
1869
1870 if (event != NB_EV_APPLY)
1871 return NB_OK;
1872
1873 circuit = yang_dnode_get_entry(dnode, true);
1874 met = yang_dnode_get_uint32(dnode, NULL);
1875 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
1876
1877 return NB_OK;
1878 }
1879
1880 /*
1881 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1882 */
1883 static int
1884 lib_interface_isis_metric_level_2_modify(enum nb_event event,
1885 const struct lyd_node *dnode,
1886 union nb_resource *resource)
1887 {
1888 struct isis_circuit *circuit;
1889 unsigned int met;
1890
1891 if (event != NB_EV_APPLY)
1892 return NB_OK;
1893
1894 circuit = yang_dnode_get_entry(dnode, true);
1895 met = yang_dnode_get_uint32(dnode, NULL);
1896 isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
1897
1898 return NB_OK;
1899 }
1900
1901 /*
1902 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
1903 */
1904 static int
1905 lib_interface_isis_priority_level_1_modify(enum nb_event event,
1906 const struct lyd_node *dnode,
1907 union nb_resource *resource)
1908 {
1909 struct isis_circuit *circuit;
1910
1911 if (event != NB_EV_APPLY)
1912 return NB_OK;
1913
1914 circuit = yang_dnode_get_entry(dnode, true);
1915 circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
1916
1917 return NB_OK;
1918 }
1919
1920 /*
1921 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1922 */
1923 static int
1924 lib_interface_isis_priority_level_2_modify(enum nb_event event,
1925 const struct lyd_node *dnode,
1926 union nb_resource *resource)
1927 {
1928 struct isis_circuit *circuit;
1929
1930 if (event != NB_EV_APPLY)
1931 return NB_OK;
1932
1933 circuit = yang_dnode_get_entry(dnode, true);
1934 circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
1935
1936 return NB_OK;
1937 }
1938
1939 /*
1940 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1941 */
1942 static int lib_interface_isis_network_type_modify(enum nb_event event,
1943 const struct lyd_node *dnode,
1944 union nb_resource *resource)
1945 {
1946 struct isis_circuit *circuit;
1947 int net_type = yang_dnode_get_enum(dnode, NULL);
1948
1949 switch (event) {
1950 case NB_EV_VALIDATE:
1951 circuit = yang_dnode_get_entry(dnode, false);
1952 if (!circuit)
1953 break;
1954 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
1955 flog_warn(
1956 EC_LIB_NB_CB_CONFIG_VALIDATE,
1957 "Cannot change network type on loopback interface");
1958 return NB_ERR_VALIDATION;
1959 }
1960 if (net_type == CIRCUIT_T_BROADCAST
1961 && circuit->state == C_STATE_UP
1962 && !if_is_broadcast(circuit->interface)) {
1963 flog_warn(
1964 EC_LIB_NB_CB_CONFIG_VALIDATE,
1965 "Cannot configure non-broadcast interface for broadcast operation");
1966 return NB_ERR_VALIDATION;
1967 }
1968 break;
1969 case NB_EV_PREPARE:
1970 case NB_EV_ABORT:
1971 break;
1972 case NB_EV_APPLY:
1973 circuit = yang_dnode_get_entry(dnode, true);
1974 isis_circuit_circ_type_set(circuit, net_type);
1975 break;
1976 }
1977
1978 return NB_OK;
1979 }
1980
1981 /*
1982 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
1983 */
1984 static int lib_interface_isis_passive_modify(enum nb_event event,
1985 const struct lyd_node *dnode,
1986 union nb_resource *resource)
1987 {
1988 struct isis_circuit *circuit;
1989 struct isis_area *area;
1990 struct interface *ifp;
1991 bool passive = yang_dnode_get_bool(dnode, NULL);
1992
1993 /* validation only applies if we are setting passive to false */
1994 if (!passive && event == NB_EV_VALIDATE) {
1995 circuit = yang_dnode_get_entry(dnode, false);
1996 if (!circuit)
1997 return NB_OK;
1998 ifp = circuit->interface;
1999 if (!ifp)
2000 return NB_OK;
2001 if (if_is_loopback(ifp)) {
2002 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
2003 "Loopback is always passive");
2004 return NB_ERR_VALIDATION;
2005 }
2006 }
2007
2008 if (event != NB_EV_APPLY)
2009 return NB_OK;
2010
2011 circuit = yang_dnode_get_entry(dnode, true);
2012 if (circuit->state != C_STATE_UP) {
2013 circuit->is_passive = passive;
2014 } else {
2015 area = circuit->area;
2016 isis_csm_state_change(ISIS_DISABLE, circuit, area);
2017 circuit->is_passive = passive;
2018 isis_csm_state_change(ISIS_ENABLE, circuit, area);
2019 }
2020
2021 return NB_OK;
2022 }
2023
2024 /*
2025 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2026 */
2027 static int lib_interface_isis_password_create(enum nb_event event,
2028 const struct lyd_node *dnode,
2029 union nb_resource *resource)
2030 {
2031 return NB_OK;
2032 }
2033
2034 static int lib_interface_isis_password_destroy(enum nb_event event,
2035 const struct lyd_node *dnode)
2036 {
2037 struct isis_circuit *circuit;
2038
2039 if (event != NB_EV_APPLY)
2040 return NB_OK;
2041
2042 circuit = yang_dnode_get_entry(dnode, true);
2043 isis_circuit_passwd_unset(circuit);
2044
2045 return NB_OK;
2046 }
2047
2048 /*
2049 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2050 */
2051 static int
2052 lib_interface_isis_password_password_modify(enum nb_event event,
2053 const struct lyd_node *dnode,
2054 union nb_resource *resource)
2055 {
2056 struct isis_circuit *circuit;
2057 const char *password;
2058
2059 if (event != NB_EV_APPLY)
2060 return NB_OK;
2061
2062 password = yang_dnode_get_string(dnode, NULL);
2063 circuit = yang_dnode_get_entry(dnode, true);
2064
2065 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
2066
2067 return NB_OK;
2068 }
2069
2070 /*
2071 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2072 */
2073 static int
2074 lib_interface_isis_password_password_type_modify(enum nb_event event,
2075 const struct lyd_node *dnode,
2076 union nb_resource *resource)
2077 {
2078 struct isis_circuit *circuit;
2079 uint8_t pass_type;
2080
2081 if (event != NB_EV_APPLY)
2082 return NB_OK;
2083
2084 pass_type = yang_dnode_get_enum(dnode, NULL);
2085 circuit = yang_dnode_get_entry(dnode, true);
2086 circuit->passwd.type = pass_type;
2087
2088 return NB_OK;
2089 }
2090
2091 /*
2092 * XPath:
2093 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2094 */
2095 static int lib_interface_isis_disable_three_way_handshake_modify(
2096 enum nb_event event, const struct lyd_node *dnode,
2097 union nb_resource *resource)
2098 {
2099 struct isis_circuit *circuit;
2100
2101 if (event != NB_EV_APPLY)
2102 return NB_OK;
2103
2104 circuit = yang_dnode_get_entry(dnode, true);
2105 circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
2106
2107 return NB_OK;
2108 }
2109
2110 /*
2111 * XPath:
2112 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2113 */
2114 static int lib_interface_isis_multi_topology_common(
2115 enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
2116 {
2117 struct isis_circuit *circuit;
2118 bool value;
2119
2120 switch (event) {
2121 case NB_EV_VALIDATE:
2122 circuit = yang_dnode_get_entry(dnode, false);
2123 if (circuit && circuit->area && circuit->area->oldmetric) {
2124 flog_warn(
2125 EC_LIB_NB_CB_CONFIG_VALIDATE,
2126 "Multi topology IS-IS can only be used with wide metrics");
2127 return NB_ERR_VALIDATION;
2128 }
2129 break;
2130 case NB_EV_PREPARE:
2131 case NB_EV_ABORT:
2132 break;
2133 case NB_EV_APPLY:
2134 circuit = yang_dnode_get_entry(dnode, true);
2135 value = yang_dnode_get_bool(dnode, NULL);
2136 isis_circuit_mt_enabled_set(circuit, mtid, value);
2137 break;
2138 }
2139
2140 return NB_OK;
2141 }
2142
2143 static int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2144 enum nb_event event, const struct lyd_node *dnode,
2145 union nb_resource *resource)
2146 {
2147 return lib_interface_isis_multi_topology_common(event, dnode,
2148 ISIS_MT_IPV4_UNICAST);
2149 }
2150
2151 /*
2152 * XPath:
2153 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2154 */
2155 static int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2156 enum nb_event event, const struct lyd_node *dnode,
2157 union nb_resource *resource)
2158 {
2159 return lib_interface_isis_multi_topology_common(event, dnode,
2160 ISIS_MT_IPV4_MULTICAST);
2161 }
2162
2163 /*
2164 * XPath:
2165 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2166 */
2167 static int lib_interface_isis_multi_topology_ipv4_management_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_MGMT);
2173 }
2174
2175 /*
2176 * XPath:
2177 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2178 */
2179 static int lib_interface_isis_multi_topology_ipv6_unicast_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_IPV6_UNICAST);
2185 }
2186
2187 /*
2188 * XPath:
2189 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2190 */
2191 static int lib_interface_isis_multi_topology_ipv6_multicast_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_IPV6_MULTICAST);
2197 }
2198
2199 /*
2200 * XPath:
2201 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2202 */
2203 static int lib_interface_isis_multi_topology_ipv6_management_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_MGMT);
2209 }
2210
2211 /*
2212 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2213 */
2214 static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2215 enum nb_event event, const struct lyd_node *dnode,
2216 union nb_resource *resource)
2217 {
2218 return lib_interface_isis_multi_topology_common(event, dnode,
2219 ISIS_MT_IPV6_DSTSRC);
2220 }
2221
2222 /*
2223 * NOTIFICATIONS
2224 */
2225 static void notif_prep_instance_hdr(const char *xpath,
2226 const struct isis_area *area,
2227 const char *routing_instance,
2228 struct list *args)
2229 {
2230 char xpath_arg[XPATH_MAXLEN];
2231 struct yang_data *data;
2232
2233 snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-instance", xpath);
2234 data = yang_data_new_string(xpath_arg, routing_instance);
2235 listnode_add(args, data);
2236 snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-protocol-name",
2237 xpath);
2238 data = yang_data_new_string(xpath_arg, area->area_tag);
2239 listnode_add(args, data);
2240 snprintf(xpath_arg, sizeof(xpath_arg), "%s/isis-level", xpath);
2241 data = yang_data_new_enum(xpath_arg, area->is_type);
2242 listnode_add(args, data);
2243 }
2244
2245 static void notif_prepr_iface_hdr(const char *xpath,
2246 const struct isis_circuit *circuit,
2247 struct list *args)
2248 {
2249 char xpath_arg[XPATH_MAXLEN];
2250 struct yang_data *data;
2251
2252 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
2253 data = yang_data_new_string(xpath_arg, circuit->interface->name);
2254 listnode_add(args, data);
2255 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-level", xpath);
2256 data = yang_data_new_enum(xpath_arg, circuit->is_type);
2257 listnode_add(args, data);
2258 snprintf(xpath_arg, sizeof(xpath_arg), "%s/extended-circuit-id", xpath);
2259 /* we do not seem to have the extended version of the circuit_id */
2260 data = yang_data_new_uint32(xpath_arg, (uint32_t)circuit->circuit_id);
2261 listnode_add(args, data);
2262 }
2263
2264 /*
2265 * XPath:
2266 * /frr-isisd:database-overload
2267 */
2268 void isis_notif_db_overload(const struct isis_area *area, bool overload)
2269 {
2270 const char *xpath = "/frr-isisd:database-overload";
2271 struct list *arguments = yang_data_list_new();
2272 char xpath_arg[XPATH_MAXLEN];
2273 struct yang_data *data;
2274
2275 notif_prep_instance_hdr(xpath, area, "default", arguments);
2276 snprintf(xpath_arg, sizeof(xpath_arg), "%s/overload", xpath);
2277 data = yang_data_new_enum(xpath_arg, !!overload);
2278 listnode_add(arguments, data);
2279
2280 nb_notification_send(xpath, arguments);
2281 }
2282
2283 /*
2284 * XPath:
2285 * /frr-isisd:lsp-too-large
2286 */
2287 void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
2288 uint32_t pdu_size, const char *lsp_id)
2289 {
2290 const char *xpath = "/frr-isisd:lsp-too-large";
2291 struct list *arguments = yang_data_list_new();
2292 char xpath_arg[XPATH_MAXLEN];
2293 struct yang_data *data;
2294 struct isis_area *area = circuit->area;
2295
2296 notif_prep_instance_hdr(xpath, area, "default", arguments);
2297 notif_prepr_iface_hdr(xpath, circuit, arguments);
2298 snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-size", xpath);
2299 data = yang_data_new_uint32(xpath_arg, pdu_size);
2300 listnode_add(arguments, data);
2301 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2302 data = yang_data_new_string(xpath_arg, lsp_id);
2303 listnode_add(arguments, data);
2304
2305 nb_notification_send(xpath, arguments);
2306 }
2307
2308 /*
2309 * XPath:
2310 * /frr-isisd:if-state-change
2311 */
2312 void isis_notif_if_state_change(const struct isis_circuit *circuit, bool down)
2313 {
2314 const char *xpath = "/frr-isisd:if-state-change";
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/state", xpath);
2323 data = yang_data_new_enum(xpath_arg, !!down);
2324 listnode_add(arguments, data);
2325
2326 nb_notification_send(xpath, arguments);
2327 }
2328
2329 /*
2330 * XPath:
2331 * /frr-isisd:corrupted-lsp-detected
2332 */
2333 void isis_notif_corrupted_lsp(const struct isis_area *area, const char *lsp_id)
2334 {
2335 const char *xpath = "/frr-isisd:corrupted-lsp-detected";
2336 struct list *arguments = yang_data_list_new();
2337 char xpath_arg[XPATH_MAXLEN];
2338 struct yang_data *data;
2339
2340 notif_prep_instance_hdr(xpath, area, "default", arguments);
2341 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2342 data = yang_data_new_string(xpath_arg, lsp_id);
2343 listnode_add(arguments, data);
2344
2345 nb_notification_send(xpath, arguments);
2346 }
2347
2348 /*
2349 * XPath:
2350 * /frr-isisd:attempt-to-exceed-max-sequence
2351 */
2352 void isis_notif_lsp_exceed_max(const struct isis_area *area, const char *lsp_id)
2353 {
2354 const char *xpath = "/frr-isisd:attempt-to-exceed-max-sequence";
2355 struct list *arguments = yang_data_list_new();
2356 char xpath_arg[XPATH_MAXLEN];
2357 struct yang_data *data;
2358
2359 notif_prep_instance_hdr(xpath, area, "default", arguments);
2360 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2361 data = yang_data_new_string(xpath_arg, lsp_id);
2362 listnode_add(arguments, data);
2363
2364 nb_notification_send(xpath, arguments);
2365 }
2366
2367 /*
2368 * XPath:
2369 * /frr-isisd:max-area-addresses-mismatch
2370 */
2371 void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
2372 uint8_t max_area_addrs,
2373 const char *raw_pdu)
2374 {
2375 const char *xpath = "/frr-isisd:max-area-addresses-mismatch";
2376 struct list *arguments = yang_data_list_new();
2377 char xpath_arg[XPATH_MAXLEN];
2378 struct yang_data *data;
2379 struct isis_area *area = circuit->area;
2380
2381 notif_prep_instance_hdr(xpath, area, "default", arguments);
2382 notif_prepr_iface_hdr(xpath, circuit, arguments);
2383 snprintf(xpath_arg, sizeof(xpath_arg), "%s/max-area-addresses", xpath);
2384 data = yang_data_new_uint8(xpath_arg, max_area_addrs);
2385 listnode_add(arguments, data);
2386 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2387 data = yang_data_new(xpath_arg, raw_pdu);
2388 listnode_add(arguments, data);
2389
2390 nb_notification_send(xpath, arguments);
2391 }
2392
2393 /*
2394 * XPath:
2395 * /frr-isisd:authentication-type-failure
2396 */
2397 void isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
2398 const char *raw_pdu)
2399 {
2400 const char *xpath = "/frr-isisd:authentication-type-failure";
2401 struct list *arguments = yang_data_list_new();
2402 char xpath_arg[XPATH_MAXLEN];
2403 struct yang_data *data;
2404 struct isis_area *area = circuit->area;
2405
2406 notif_prep_instance_hdr(xpath, area, "default", arguments);
2407 notif_prepr_iface_hdr(xpath, circuit, arguments);
2408 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2409 data = yang_data_new(xpath_arg, raw_pdu);
2410 listnode_add(arguments, data);
2411
2412 nb_notification_send(xpath, arguments);
2413 }
2414
2415 /*
2416 * XPath:
2417 * /frr-isisd:authentication-failure
2418 */
2419 void isis_notif_authentication_failure(const struct isis_circuit *circuit,
2420 const char *raw_pdu)
2421 {
2422 const char *xpath = "/frr-isisd:authentication-failure";
2423 struct list *arguments = yang_data_list_new();
2424 char xpath_arg[XPATH_MAXLEN];
2425 struct yang_data *data;
2426 struct isis_area *area = circuit->area;
2427
2428 notif_prep_instance_hdr(xpath, area, "default", arguments);
2429 notif_prepr_iface_hdr(xpath, circuit, arguments);
2430 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2431 data = yang_data_new(xpath_arg, raw_pdu);
2432 listnode_add(arguments, data);
2433
2434 nb_notification_send(xpath, arguments);
2435 }
2436
2437 /*
2438 * XPath:
2439 * /frr-isisd:adjacency-state-change
2440 */
2441 void isis_notif_adj_state_change(const struct isis_adjacency *adj,
2442 int new_state, const char *reason)
2443 {
2444 const char *xpath = "/frr-isisd:adjacency-state-change";
2445 struct list *arguments = yang_data_list_new();
2446 char xpath_arg[XPATH_MAXLEN];
2447 struct yang_data *data;
2448 struct isis_circuit *circuit = adj->circuit;
2449 struct isis_area *area = circuit->area;
2450 struct isis_dynhn *dyn = dynhn_find_by_id(adj->sysid);
2451
2452 notif_prep_instance_hdr(xpath, area, "default", arguments);
2453 notif_prepr_iface_hdr(xpath, circuit, arguments);
2454 if (dyn) {
2455 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor", xpath);
2456 data = yang_data_new_string(xpath_arg, dyn->hostname);
2457 listnode_add(arguments, data);
2458 }
2459 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
2460 data = yang_data_new_string(xpath_arg, sysid_print(adj->sysid));
2461 listnode_add(arguments, data);
2462
2463 snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
2464 switch (new_state) {
2465 case ISIS_ADJ_DOWN:
2466 data = yang_data_new_string(xpath_arg, "down");
2467 break;
2468 case ISIS_ADJ_UP:
2469 data = yang_data_new_string(xpath_arg, "up");
2470 break;
2471 case ISIS_ADJ_INITIALIZING:
2472 data = yang_data_new_string(xpath_arg, "init");
2473 break;
2474 default:
2475 data = yang_data_new_string(xpath_arg, "failed");
2476 }
2477 listnode_add(arguments, data);
2478 if (new_state == ISIS_ADJ_DOWN) {
2479 snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
2480 data = yang_data_new_string(xpath_arg, reason);
2481 listnode_add(arguments, data);
2482 }
2483
2484 nb_notification_send(xpath, arguments);
2485 }
2486
2487 /*
2488 * XPath:
2489 * /frr-isisd:rejected-adjacency
2490 */
2491 void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
2492 const char *reason, const char *raw_pdu)
2493 {
2494 const char *xpath = "/frr-isisd:rejected-adjacency";
2495 struct list *arguments = yang_data_list_new();
2496 char xpath_arg[XPATH_MAXLEN];
2497 struct yang_data *data;
2498 struct isis_area *area = circuit->area;
2499
2500 notif_prep_instance_hdr(xpath, area, "default", arguments);
2501 notif_prepr_iface_hdr(xpath, circuit, arguments);
2502 snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
2503 data = yang_data_new_string(xpath_arg, reason);
2504 listnode_add(arguments, data);
2505 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2506 data = yang_data_new(xpath_arg, raw_pdu);
2507 listnode_add(arguments, data);
2508
2509 nb_notification_send(xpath, arguments);
2510 }
2511
2512 /*
2513 * XPath:
2514 * /frr-isisd:area-mismatch
2515 */
2516 void isis_notif_area_mismatch(const struct isis_circuit *circuit,
2517 const char *raw_pdu)
2518 {
2519 const char *xpath = "/frr-isisd:area-mismatch";
2520 struct list *arguments = yang_data_list_new();
2521 char xpath_arg[XPATH_MAXLEN];
2522 struct yang_data *data;
2523 struct isis_area *area = circuit->area;
2524
2525 notif_prep_instance_hdr(xpath, area, "default", arguments);
2526 notif_prepr_iface_hdr(xpath, circuit, arguments);
2527 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2528 data = yang_data_new(xpath_arg, raw_pdu);
2529 listnode_add(arguments, data);
2530
2531 nb_notification_send(xpath, arguments);
2532 }
2533
2534 /*
2535 * XPath:
2536 * /frr-isisd:lsp-received
2537 */
2538 void isis_notif_lsp_received(const struct isis_circuit *circuit,
2539 const char *lsp_id, uint32_t seqno,
2540 uint32_t timestamp, const char *sys_id)
2541 {
2542 const char *xpath = "/frr-isisd:lsp-received";
2543 struct list *arguments = yang_data_list_new();
2544 char xpath_arg[XPATH_MAXLEN];
2545 struct yang_data *data;
2546 struct isis_area *area = circuit->area;
2547
2548 notif_prep_instance_hdr(xpath, area, "default", arguments);
2549 notif_prepr_iface_hdr(xpath, circuit, arguments);
2550 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2551 data = yang_data_new_string(xpath_arg, lsp_id);
2552 listnode_add(arguments, data);
2553 snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
2554 data = yang_data_new_uint32(xpath_arg, seqno);
2555 listnode_add(arguments, data);
2556 snprintf(xpath_arg, sizeof(xpath_arg), "%s/received-timestamp", xpath);
2557 data = yang_data_new_uint32(xpath_arg, timestamp);
2558 listnode_add(arguments, data);
2559 snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
2560 data = yang_data_new_string(xpath_arg, sys_id);
2561 listnode_add(arguments, data);
2562
2563 nb_notification_send(xpath, arguments);
2564 }
2565
2566 /*
2567 * XPath:
2568 * /frr-isisd:lsp-generation
2569 */
2570 void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id,
2571 uint32_t seqno, uint32_t timestamp)
2572 {
2573 const char *xpath = "/frr-isisd:lsp-generation";
2574 struct list *arguments = yang_data_list_new();
2575 char xpath_arg[XPATH_MAXLEN];
2576 struct yang_data *data;
2577
2578 notif_prep_instance_hdr(xpath, area, "default", arguments);
2579 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2580 data = yang_data_new_string(xpath_arg, lsp_id);
2581 listnode_add(arguments, data);
2582 snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
2583 data = yang_data_new_uint32(xpath_arg, seqno);
2584 listnode_add(arguments, data);
2585 snprintf(xpath_arg, sizeof(xpath_arg), "%s/send-timestamp", xpath);
2586 data = yang_data_new_uint32(xpath_arg, timestamp);
2587 listnode_add(arguments, data);
2588
2589 nb_notification_send(xpath, arguments);
2590 }
2591
2592 /*
2593 * XPath:
2594 * /frr-isisd:id-len-mismatch
2595 */
2596 void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
2597 uint8_t rcv_id_len, const char *raw_pdu)
2598 {
2599 const char *xpath = "/frr-isisd:id-len-mismatch";
2600 struct list *arguments = yang_data_list_new();
2601 char xpath_arg[XPATH_MAXLEN];
2602 struct yang_data *data;
2603 struct isis_area *area = circuit->area;
2604
2605 notif_prep_instance_hdr(xpath, area, "default", arguments);
2606 notif_prepr_iface_hdr(xpath, circuit, arguments);
2607 snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-field-len", xpath);
2608 data = yang_data_new_uint8(xpath_arg, rcv_id_len);
2609 listnode_add(arguments, data);
2610 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2611 data = yang_data_new(xpath_arg, raw_pdu);
2612 listnode_add(arguments, data);
2613
2614 nb_notification_send(xpath, arguments);
2615 }
2616
2617 /*
2618 * XPath:
2619 * /frr-isisd:version-skew
2620 */
2621 void isis_notif_version_skew(const struct isis_circuit *circuit,
2622 uint8_t version, const char *raw_pdu)
2623 {
2624 const char *xpath = "/frr-isisd:version-skew";
2625 struct list *arguments = yang_data_list_new();
2626 char xpath_arg[XPATH_MAXLEN];
2627 struct yang_data *data;
2628 struct isis_area *area = circuit->area;
2629
2630 notif_prep_instance_hdr(xpath, area, "default", arguments);
2631 notif_prepr_iface_hdr(xpath, circuit, arguments);
2632 snprintf(xpath_arg, sizeof(xpath_arg), "%s/protocol-version", xpath);
2633 data = yang_data_new_uint8(xpath_arg, version);
2634 listnode_add(arguments, data);
2635 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2636 data = yang_data_new(xpath_arg, raw_pdu);
2637 listnode_add(arguments, data);
2638
2639 nb_notification_send(xpath, arguments);
2640 }
2641
2642 /*
2643 * XPath:
2644 * /frr-isisd:lsp-error-detected
2645 */
2646 void isis_notif_lsp_error(const struct isis_circuit *circuit,
2647 const char *lsp_id, const char *raw_pdu,
2648 __attribute__((unused)) uint32_t offset,
2649 __attribute__((unused)) uint8_t tlv_type)
2650 {
2651 const char *xpath = "/frr-isisd:lsp-error-detected";
2652 struct list *arguments = yang_data_list_new();
2653 char xpath_arg[XPATH_MAXLEN];
2654 struct yang_data *data;
2655 struct isis_area *area = circuit->area;
2656
2657 notif_prep_instance_hdr(xpath, area, "default", arguments);
2658 notif_prepr_iface_hdr(xpath, circuit, arguments);
2659 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2660 data = yang_data_new_string(xpath_arg, lsp_id);
2661 listnode_add(arguments, data);
2662 snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
2663 data = yang_data_new(xpath_arg, raw_pdu);
2664 listnode_add(arguments, data);
2665 /* ignore offset and tlv_type which cannot be set properly */
2666
2667 nb_notification_send(xpath, arguments);
2668 }
2669
2670 /*
2671 * XPath:
2672 * /frr-isisd:sequence-number-skipped
2673 */
2674 void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
2675 const char *lsp_id)
2676 {
2677 const char *xpath = "/frr-isisd:sequence-number-skipped";
2678 struct list *arguments = yang_data_list_new();
2679 char xpath_arg[XPATH_MAXLEN];
2680 struct yang_data *data;
2681 struct isis_area *area = circuit->area;
2682
2683 notif_prep_instance_hdr(xpath, area, "default", arguments);
2684 notif_prepr_iface_hdr(xpath, circuit, arguments);
2685 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2686 data = yang_data_new_string(xpath_arg, lsp_id);
2687 listnode_add(arguments, data);
2688
2689 nb_notification_send(xpath, arguments);
2690 }
2691
2692 /*
2693 * XPath:
2694 * /frr-isisd:own-lsp-purge
2695 */
2696 void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
2697 const char *lsp_id)
2698 {
2699 const char *xpath = "/frr-isisd:own-lsp-purge";
2700 struct list *arguments = yang_data_list_new();
2701 char xpath_arg[XPATH_MAXLEN];
2702 struct yang_data *data;
2703 struct isis_area *area = circuit->area;
2704
2705 notif_prep_instance_hdr(xpath, area, "default", arguments);
2706 notif_prepr_iface_hdr(xpath, circuit, arguments);
2707 snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
2708 data = yang_data_new_string(xpath_arg, lsp_id);
2709 listnode_add(arguments, data);
2710
2711 nb_notification_send(xpath, arguments);
2712 }
2713
2714 /* clang-format off */
2715 const struct frr_yang_module_info frr_isisd_info = {
2716 .name = "frr-isisd",
2717 .nodes = {
2718 {
2719 .xpath = "/frr-isisd:isis/instance",
2720 .cbs.create = isis_instance_create,
2721 .cbs.destroy = isis_instance_destroy,
2722 .cbs.cli_show = cli_show_router_isis,
2723 .priority = NB_DFLT_PRIORITY - 1,
2724 },
2725 {
2726 .xpath = "/frr-isisd:isis/instance/is-type",
2727 .cbs.modify = isis_instance_is_type_modify,
2728 .cbs.cli_show = cli_show_isis_is_type,
2729 },
2730 {
2731 .xpath = "/frr-isisd:isis/instance/area-address",
2732 .cbs.create = isis_instance_area_address_create,
2733 .cbs.destroy = isis_instance_area_address_destroy,
2734 .cbs.cli_show = cli_show_isis_area_address,
2735 },
2736 {
2737 .xpath = "/frr-isisd:isis/instance/dynamic-hostname",
2738 .cbs.modify = isis_instance_dynamic_hostname_modify,
2739 .cbs.cli_show = cli_show_isis_dynamic_hostname,
2740 },
2741 {
2742 .xpath = "/frr-isisd:isis/instance/attached",
2743 .cbs.modify = isis_instance_attached_modify,
2744 .cbs.cli_show = cli_show_isis_attached,
2745 },
2746 {
2747 .xpath = "/frr-isisd:isis/instance/overload",
2748 .cbs.modify = isis_instance_overload_modify,
2749 .cbs.cli_show = cli_show_isis_overload,
2750 },
2751 {
2752 .xpath = "/frr-isisd:isis/instance/metric-style",
2753 .cbs.modify = isis_instance_metric_style_modify,
2754 .cbs.cli_show = cli_show_isis_metric_style,
2755 },
2756 {
2757 .xpath = "/frr-isisd:isis/instance/purge-originator",
2758 .cbs.modify = isis_instance_purge_originator_modify,
2759 .cbs.cli_show = cli_show_isis_purge_origin,
2760 },
2761 {
2762 .xpath = "/frr-isisd:isis/instance/lsp/mtu",
2763 .cbs.modify = isis_instance_lsp_mtu_modify,
2764 .cbs.cli_show = cli_show_isis_lsp_mtu,
2765 },
2766 {
2767 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval",
2768 .cbs.cli_show = cli_show_isis_lsp_ref_interval,
2769 },
2770 {
2771 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-1",
2772 .cbs.modify = isis_instance_lsp_refresh_interval_level_1_modify,
2773 },
2774 {
2775 .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-2",
2776 .cbs.modify = isis_instance_lsp_refresh_interval_level_2_modify,
2777 },
2778 {
2779 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime",
2780 .cbs.cli_show = cli_show_isis_lsp_max_lifetime,
2781 },
2782 {
2783 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1",
2784 .cbs.modify = isis_instance_lsp_maximum_lifetime_level_1_modify,
2785 },
2786 {
2787 .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2",
2788 .cbs.modify = isis_instance_lsp_maximum_lifetime_level_2_modify,
2789 },
2790 {
2791 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval",
2792 .cbs.cli_show = cli_show_isis_lsp_gen_interval,
2793 },
2794 {
2795 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-1",
2796 .cbs.modify = isis_instance_lsp_generation_interval_level_1_modify,
2797 },
2798 {
2799 .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-2",
2800 .cbs.modify = isis_instance_lsp_generation_interval_level_2_modify,
2801 },
2802 {
2803 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay",
2804 .cbs.create = isis_instance_spf_ietf_backoff_delay_create,
2805 .cbs.destroy = isis_instance_spf_ietf_backoff_delay_destroy,
2806 .cbs.apply_finish = ietf_backoff_delay_apply_finish,
2807 .cbs.cli_show = cli_show_isis_spf_ietf_backoff,
2808 },
2809 {
2810 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay",
2811 .cbs.modify = isis_instance_spf_ietf_backoff_delay_init_delay_modify,
2812 },
2813 {
2814 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay",
2815 .cbs.modify = isis_instance_spf_ietf_backoff_delay_short_delay_modify,
2816 },
2817 {
2818 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay",
2819 .cbs.modify = isis_instance_spf_ietf_backoff_delay_long_delay_modify,
2820 },
2821 {
2822 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down",
2823 .cbs.modify = isis_instance_spf_ietf_backoff_delay_hold_down_modify,
2824 },
2825 {
2826 .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn",
2827 .cbs.modify = isis_instance_spf_ietf_backoff_delay_time_to_learn_modify,
2828 },
2829 {
2830 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval",
2831 .cbs.cli_show = cli_show_isis_spf_min_interval,
2832 },
2833 {
2834 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-1",
2835 .cbs.modify = isis_instance_spf_minimum_interval_level_1_modify,
2836 },
2837 {
2838 .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-2",
2839 .cbs.modify = isis_instance_spf_minimum_interval_level_2_modify,
2840 },
2841 {
2842 .xpath = "/frr-isisd:isis/instance/area-password",
2843 .cbs.create = isis_instance_area_password_create,
2844 .cbs.destroy = isis_instance_area_password_destroy,
2845 .cbs.apply_finish = area_password_apply_finish,
2846 .cbs.cli_show = cli_show_isis_area_pwd,
2847 },
2848 {
2849 .xpath = "/frr-isisd:isis/instance/area-password/password",
2850 .cbs.modify = isis_instance_area_password_password_modify,
2851 },
2852 {
2853 .xpath = "/frr-isisd:isis/instance/area-password/password-type",
2854 .cbs.modify = isis_instance_area_password_password_type_modify,
2855 },
2856 {
2857 .xpath = "/frr-isisd:isis/instance/area-password/authenticate-snp",
2858 .cbs.modify = isis_instance_area_password_authenticate_snp_modify,
2859 },
2860 {
2861 .xpath = "/frr-isisd:isis/instance/domain-password",
2862 .cbs.create = isis_instance_domain_password_create,
2863 .cbs.destroy = isis_instance_domain_password_destroy,
2864 .cbs.apply_finish = domain_password_apply_finish,
2865 .cbs.cli_show = cli_show_isis_domain_pwd,
2866 },
2867 {
2868 .xpath = "/frr-isisd:isis/instance/domain-password/password",
2869 .cbs.modify = isis_instance_domain_password_password_modify,
2870 },
2871 {
2872 .xpath = "/frr-isisd:isis/instance/domain-password/password-type",
2873 .cbs.modify = isis_instance_domain_password_password_type_modify,
2874 },
2875 {
2876 .xpath = "/frr-isisd:isis/instance/domain-password/authenticate-snp",
2877 .cbs.modify = isis_instance_domain_password_authenticate_snp_modify,
2878 },
2879 {
2880 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
2881 .cbs.create = isis_instance_default_information_originate_ipv4_create,
2882 .cbs.destroy = isis_instance_default_information_originate_ipv4_destroy,
2883 .cbs.apply_finish = default_info_origin_ipv4_apply_finish,
2884 .cbs.cli_show = cli_show_isis_def_origin_ipv4,
2885 },
2886 {
2887 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
2888 .cbs.modify = isis_instance_default_information_originate_ipv4_always_modify,
2889 },
2890 {
2891 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/route-map",
2892 .cbs.modify = isis_instance_default_information_originate_ipv4_route_map_modify,
2893 .cbs.destroy = isis_instance_default_information_originate_ipv4_route_map_destroy,
2894 },
2895 {
2896 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/metric",
2897 .cbs.modify = isis_instance_default_information_originate_ipv4_metric_modify,
2898 },
2899 {
2900 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
2901 .cbs.create = isis_instance_default_information_originate_ipv6_create,
2902 .cbs.destroy = isis_instance_default_information_originate_ipv6_destroy,
2903 .cbs.apply_finish = default_info_origin_ipv6_apply_finish,
2904 .cbs.cli_show = cli_show_isis_def_origin_ipv6,
2905 },
2906 {
2907 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
2908 .cbs.modify = isis_instance_default_information_originate_ipv6_always_modify,
2909 },
2910 {
2911 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/route-map",
2912 .cbs.modify = isis_instance_default_information_originate_ipv6_route_map_modify,
2913 .cbs.destroy = isis_instance_default_information_originate_ipv6_route_map_destroy,
2914 },
2915 {
2916 .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/metric",
2917 .cbs.modify = isis_instance_default_information_originate_ipv6_metric_modify,
2918 },
2919 {
2920 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4",
2921 .cbs.create = isis_instance_redistribute_ipv4_create,
2922 .cbs.destroy = isis_instance_redistribute_ipv4_destroy,
2923 .cbs.apply_finish = redistribute_ipv4_apply_finish,
2924 .cbs.cli_show = cli_show_isis_redistribute_ipv4,
2925 },
2926 {
2927 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/route-map",
2928 .cbs.modify = isis_instance_redistribute_ipv4_route_map_modify,
2929 .cbs.destroy = isis_instance_redistribute_ipv4_route_map_destroy,
2930 },
2931 {
2932 .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",
2933 .cbs.modify = isis_instance_redistribute_ipv4_metric_modify,
2934 },
2935 {
2936 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6",
2937 .cbs.create = isis_instance_redistribute_ipv6_create,
2938 .cbs.destroy = isis_instance_redistribute_ipv6_destroy,
2939 .cbs.apply_finish = redistribute_ipv6_apply_finish,
2940 .cbs.cli_show = cli_show_isis_redistribute_ipv6,
2941 },
2942 {
2943 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/route-map",
2944 .cbs.modify = isis_instance_redistribute_ipv6_route_map_modify,
2945 .cbs.destroy = isis_instance_redistribute_ipv6_route_map_destroy,
2946 },
2947 {
2948 .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",
2949 .cbs.modify = isis_instance_redistribute_ipv6_metric_modify,
2950 },
2951 {
2952 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast",
2953 .cbs.create = isis_instance_multi_topology_ipv4_multicast_create,
2954 .cbs.destroy = isis_instance_multi_topology_ipv4_multicast_destroy,
2955 .cbs.cli_show = cli_show_isis_mt_ipv4_multicast,
2956 },
2957 {
2958 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload",
2959 .cbs.modify = isis_instance_multi_topology_ipv4_multicast_overload_modify,
2960 },
2961 {
2962 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management",
2963 .cbs.create = isis_instance_multi_topology_ipv4_management_create,
2964 .cbs.destroy = isis_instance_multi_topology_ipv4_management_destroy,
2965 .cbs.cli_show = cli_show_isis_mt_ipv4_mgmt,
2966 },
2967 {
2968 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management/overload",
2969 .cbs.modify = isis_instance_multi_topology_ipv4_management_overload_modify,
2970 },
2971 {
2972 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast",
2973 .cbs.create = isis_instance_multi_topology_ipv6_unicast_create,
2974 .cbs.destroy = isis_instance_multi_topology_ipv6_unicast_destroy,
2975 .cbs.cli_show = cli_show_isis_mt_ipv6_unicast,
2976 },
2977 {
2978 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload",
2979 .cbs.modify = isis_instance_multi_topology_ipv6_unicast_overload_modify,
2980 },
2981 {
2982 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast",
2983 .cbs.create = isis_instance_multi_topology_ipv6_multicast_create,
2984 .cbs.destroy = isis_instance_multi_topology_ipv6_multicast_destroy,
2985 .cbs.cli_show = cli_show_isis_mt_ipv6_multicast,
2986 },
2987 {
2988 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload",
2989 .cbs.modify = isis_instance_multi_topology_ipv6_multicast_overload_modify,
2990 },
2991 {
2992 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management",
2993 .cbs.create = isis_instance_multi_topology_ipv6_management_create,
2994 .cbs.destroy = isis_instance_multi_topology_ipv6_management_destroy,
2995 .cbs.cli_show = cli_show_isis_mt_ipv6_mgmt,
2996 },
2997 {
2998 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management/overload",
2999 .cbs.modify = isis_instance_multi_topology_ipv6_management_overload_modify,
3000 },
3001 {
3002 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc",
3003 .cbs.create = isis_instance_multi_topology_ipv6_dstsrc_create,
3004 .cbs.destroy = isis_instance_multi_topology_ipv6_dstsrc_destroy,
3005 .cbs.cli_show = cli_show_isis_mt_ipv6_dstsrc,
3006 },
3007 {
3008 .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload",
3009 .cbs.modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify,
3010 },
3011 {
3012 .xpath = "/frr-isisd:isis/instance/log-adjacency-changes",
3013 .cbs.modify = isis_instance_log_adjacency_changes_modify,
3014 .cbs.cli_show = cli_show_isis_log_adjacency,
3015 },
3016 {
3017 .xpath = "/frr-isisd:isis/mpls-te",
3018 .cbs.create = isis_mpls_te_create,
3019 .cbs.destroy = isis_mpls_te_destroy,
3020 .cbs.cli_show = cli_show_isis_mpls_te,
3021 },
3022 {
3023 .xpath = "/frr-isisd:isis/mpls-te/router-address",
3024 .cbs.modify = isis_mpls_te_router_address_modify,
3025 .cbs.destroy = isis_mpls_te_router_address_destroy,
3026 .cbs.cli_show = cli_show_isis_mpls_te_router_addr,
3027 },
3028 {
3029 .xpath = "/frr-interface:lib/interface/frr-isisd:isis",
3030 .cbs.create = lib_interface_isis_create,
3031 .cbs.destroy = lib_interface_isis_destroy,
3032 },
3033 {
3034 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/area-tag",
3035 .cbs.modify = lib_interface_isis_area_tag_modify,
3036 },
3037 {
3038 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type",
3039 .cbs.modify = lib_interface_isis_circuit_type_modify,
3040 .cbs.cli_show = cli_show_ip_isis_circ_type,
3041 },
3042 {
3043 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing",
3044 .cbs.modify = lib_interface_isis_ipv4_routing_modify,
3045 .cbs.cli_show = cli_show_ip_isis_ipv4,
3046 },
3047 {
3048 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing",
3049 .cbs.modify = lib_interface_isis_ipv6_routing_modify,
3050 .cbs.cli_show = cli_show_ip_isis_ipv6,
3051 },
3052 {
3053 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval",
3054 .cbs.cli_show = cli_show_ip_isis_csnp_interval,
3055 },
3056 {
3057 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1",
3058 .cbs.modify = lib_interface_isis_csnp_interval_level_1_modify,
3059 },
3060 {
3061 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2",
3062 .cbs.modify = lib_interface_isis_csnp_interval_level_2_modify,
3063 },
3064 {
3065 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval",
3066 .cbs.cli_show = cli_show_ip_isis_psnp_interval,
3067 },
3068 {
3069 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1",
3070 .cbs.modify = lib_interface_isis_psnp_interval_level_1_modify,
3071 },
3072 {
3073 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2",
3074 .cbs.modify = lib_interface_isis_psnp_interval_level_2_modify,
3075 },
3076 {
3077 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/padding",
3078 .cbs.modify = lib_interface_isis_hello_padding_modify,
3079 .cbs.cli_show = cli_show_ip_isis_hello_padding,
3080 },
3081 {
3082 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval",
3083 .cbs.cli_show = cli_show_ip_isis_hello_interval,
3084 },
3085 {
3086 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1",
3087 .cbs.modify = lib_interface_isis_hello_interval_level_1_modify,
3088 },
3089 {
3090 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2",
3091 .cbs.modify = lib_interface_isis_hello_interval_level_2_modify,
3092 },
3093 {
3094 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier",
3095 .cbs.cli_show = cli_show_ip_isis_hello_multi,
3096 },
3097 {
3098 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1",
3099 .cbs.modify = lib_interface_isis_hello_multiplier_level_1_modify,
3100 },
3101 {
3102 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2",
3103 .cbs.modify = lib_interface_isis_hello_multiplier_level_2_modify,
3104 },
3105 {
3106 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric",
3107 .cbs.cli_show = cli_show_ip_isis_metric,
3108 },
3109 {
3110 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1",
3111 .cbs.modify = lib_interface_isis_metric_level_1_modify,
3112 },
3113 {
3114 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2",
3115 .cbs.modify = lib_interface_isis_metric_level_2_modify,
3116 },
3117 {
3118 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority",
3119 .cbs.cli_show = cli_show_ip_isis_priority,
3120 },
3121 {
3122 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1",
3123 .cbs.modify = lib_interface_isis_priority_level_1_modify,
3124 },
3125 {
3126 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2",
3127 .cbs.modify = lib_interface_isis_priority_level_2_modify,
3128 },
3129 {
3130 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/network-type",
3131 .cbs.modify = lib_interface_isis_network_type_modify,
3132 .cbs.cli_show = cli_show_ip_isis_network_type,
3133 },
3134 {
3135 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/passive",
3136 .cbs.modify = lib_interface_isis_passive_modify,
3137 .cbs.cli_show = cli_show_ip_isis_passive,
3138 },
3139 {
3140 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password",
3141 .cbs.create = lib_interface_isis_password_create,
3142 .cbs.destroy = lib_interface_isis_password_destroy,
3143 .cbs.cli_show = cli_show_ip_isis_password,
3144 },
3145 {
3146 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password",
3147 .cbs.modify = lib_interface_isis_password_password_modify,
3148 },
3149 {
3150 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password-type",
3151 .cbs.modify = lib_interface_isis_password_password_type_modify,
3152 },
3153 {
3154 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake",
3155 .cbs.modify = lib_interface_isis_disable_three_way_handshake_modify,
3156 .cbs.cli_show = cli_show_ip_isis_threeway_shake,
3157 },
3158 {
3159 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast",
3160 .cbs.modify = lib_interface_isis_multi_topology_ipv4_unicast_modify,
3161 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_unicast,
3162 },
3163 {
3164 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast",
3165 .cbs.modify = lib_interface_isis_multi_topology_ipv4_multicast_modify,
3166 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_multicast,
3167 },
3168 {
3169 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management",
3170 .cbs.modify = lib_interface_isis_multi_topology_ipv4_management_modify,
3171 .cbs.cli_show = cli_show_ip_isis_mt_ipv4_mgmt,
3172 },
3173 {
3174 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast",
3175 .cbs.modify = lib_interface_isis_multi_topology_ipv6_unicast_modify,
3176 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_unicast,
3177 },
3178 {
3179 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast",
3180 .cbs.modify = lib_interface_isis_multi_topology_ipv6_multicast_modify,
3181 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_multicast,
3182 },
3183 {
3184 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management",
3185 .cbs.modify = lib_interface_isis_multi_topology_ipv6_management_modify,
3186 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_mgmt,
3187 },
3188 {
3189 .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc",
3190 .cbs.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
3191 .cbs.cli_show = cli_show_ip_isis_mt_ipv6_dstsrc,
3192 },
3193 {
3194 .xpath = NULL,
3195 },
3196 }
3197 };