2 * Copyright (C) 2001,2002 Sampo Saaristo
3 * Tampere University of Technology
4 * Institute of Communications Engineering
5 * Copyright (C) 2018 Volta Networks
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)
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
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
25 #include "northbound.h"
29 #include "spf_backoff.h"
30 #include "lib_errors.h"
33 #include "isisd/isisd.h"
34 #include "isisd/isis_nb.h"
35 #include "isisd/isis_common.h"
36 #include "isisd/isis_bfd.h"
37 #include "isisd/isis_circuit.h"
38 #include "isisd/isis_lsp.h"
39 #include "isisd/isis_dynhn.h"
40 #include "isisd/isis_misc.h"
41 #include "isisd/isis_csm.h"
42 #include "isisd/isis_adjacency.h"
43 #include "isisd/isis_spf.h"
44 #include "isisd/isis_te.h"
45 #include "isisd/isis_memory.h"
46 #include "isisd/isis_mt.h"
47 #include "isisd/isis_redist.h"
50 * XPath: /frr-isisd:isis/instance
52 int isis_instance_create(enum nb_event event
, const struct lyd_node
*dnode
,
53 union nb_resource
*resource
)
55 struct isis_area
*area
;
58 if (event
!= NB_EV_APPLY
)
61 area_tag
= yang_dnode_get_string(dnode
, "./area-tag");
62 area
= isis_area_lookup(area_tag
);
64 return NB_ERR_INCONSISTENCY
;
66 area
= isis_area_create(area_tag
);
67 /* save area in dnode to avoid looking it up all the time */
68 nb_running_set_entry(dnode
, area
);
73 int isis_instance_destroy(enum nb_event event
, const struct lyd_node
*dnode
)
75 struct isis_area
*area
;
77 if (event
!= NB_EV_APPLY
)
80 area
= nb_running_unset_entry(dnode
);
81 isis_area_destroy(area
->area_tag
);
87 * XPath: /frr-isisd:isis/instance/is-type
89 int isis_instance_is_type_modify(enum nb_event event
,
90 const struct lyd_node
*dnode
,
91 union nb_resource
*resource
)
93 struct isis_area
*area
;
96 if (event
!= NB_EV_APPLY
)
99 area
= nb_running_get_entry(dnode
, NULL
, true);
100 type
= yang_dnode_get_enum(dnode
, NULL
);
101 isis_area_is_type_set(area
, type
);
107 * XPath: /frr-isisd:isis/instance/area-address
109 int isis_instance_area_address_create(enum nb_event event
,
110 const struct lyd_node
*dnode
,
111 union nb_resource
*resource
)
113 struct isis_area
*area
;
114 struct area_addr addr
, *addrr
= NULL
, *addrp
= NULL
;
115 struct listnode
*node
;
117 const char *net_title
= yang_dnode_get_string(dnode
, NULL
);
121 addr
.addr_len
= dotformat2buff(buff
, net_title
);
122 memcpy(addr
.area_addr
, buff
, addr
.addr_len
);
123 if (addr
.area_addr
[addr
.addr_len
- 1] != 0) {
125 EC_LIB_NB_CB_CONFIG_VALIDATE
,
126 "nsel byte (last byte) in area address must be 0");
127 return NB_ERR_VALIDATION
;
129 if (isis
->sysid_set
) {
130 /* Check that the SystemID portions match */
131 if (memcmp(isis
->sysid
, GETSYSID((&addr
)),
134 EC_LIB_NB_CB_CONFIG_VALIDATE
,
135 "System ID must not change when defining additional area addresses");
136 return NB_ERR_VALIDATION
;
141 addrr
= XMALLOC(MTYPE_ISIS_AREA_ADDR
, sizeof(struct area_addr
));
142 addrr
->addr_len
= dotformat2buff(buff
, net_title
);
143 memcpy(addrr
->area_addr
, buff
, addrr
->addr_len
);
144 resource
->ptr
= addrr
;
147 XFREE(MTYPE_ISIS_AREA_ADDR
, resource
->ptr
);
150 area
= nb_running_get_entry(dnode
, NULL
, true);
151 addrr
= resource
->ptr
;
153 if (isis
->sysid_set
== 0) {
155 * First area address - get the SystemID for this router
157 memcpy(isis
->sysid
, GETSYSID(addrr
), ISIS_SYS_ID_LEN
);
160 /* check that we don't already have this address */
161 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node
,
163 if ((addrp
->addr_len
+ ISIS_SYS_ID_LEN
165 != (addrr
->addr_len
))
167 if (!memcmp(addrp
->area_addr
, addrr
->area_addr
,
169 XFREE(MTYPE_ISIS_AREA_ADDR
, addrr
);
170 return NB_OK
; /* silent fail */
175 /*Forget the systemID part of the address */
176 addrr
->addr_len
-= (ISIS_SYS_ID_LEN
+ ISIS_NSEL_LEN
);
177 assert(area
->area_addrs
); /* to silence scan-build sillyness */
178 listnode_add(area
->area_addrs
, addrr
);
180 /* only now we can safely generate our LSPs for this area */
181 if (listcount(area
->area_addrs
) > 0) {
182 if (area
->is_type
& IS_LEVEL_1
)
183 lsp_generate(area
, IS_LEVEL_1
);
184 if (area
->is_type
& IS_LEVEL_2
)
185 lsp_generate(area
, IS_LEVEL_2
);
193 int isis_instance_area_address_destroy(enum nb_event event
,
194 const struct lyd_node
*dnode
)
196 struct area_addr addr
, *addrp
= NULL
;
197 struct listnode
*node
;
199 struct isis_area
*area
;
200 const char *net_title
;
202 if (event
!= NB_EV_APPLY
)
205 net_title
= yang_dnode_get_string(dnode
, NULL
);
206 addr
.addr_len
= dotformat2buff(buff
, net_title
);
207 memcpy(addr
.area_addr
, buff
, (int)addr
.addr_len
);
208 area
= nb_running_get_entry(dnode
, NULL
, true);
209 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, node
, addrp
)) {
210 if ((addrp
->addr_len
+ ISIS_SYS_ID_LEN
+ 1) == addr
.addr_len
211 && !memcmp(addrp
->area_addr
, addr
.area_addr
, addr
.addr_len
))
215 return NB_ERR_INCONSISTENCY
;
217 listnode_delete(area
->area_addrs
, addrp
);
218 XFREE(MTYPE_ISIS_AREA_ADDR
, addrp
);
220 * Last area address - reset the SystemID for this router
222 if (listcount(area
->area_addrs
) == 0) {
223 memset(isis
->sysid
, 0, ISIS_SYS_ID_LEN
);
225 if (isis
->debugs
& DEBUG_EVENTS
)
226 zlog_debug("Router has no SystemID");
233 * XPath: /frr-isisd:isis/instance/dynamic-hostname
235 int isis_instance_dynamic_hostname_modify(enum nb_event event
,
236 const struct lyd_node
*dnode
,
237 union nb_resource
*resource
)
239 struct isis_area
*area
;
241 if (event
!= NB_EV_APPLY
)
244 area
= nb_running_get_entry(dnode
, NULL
, true);
245 isis_area_dynhostname_set(area
, yang_dnode_get_bool(dnode
, NULL
));
251 * XPath: /frr-isisd:isis/instance/attached
253 int isis_instance_attached_modify(enum nb_event event
,
254 const struct lyd_node
*dnode
,
255 union nb_resource
*resource
)
257 struct isis_area
*area
;
260 if (event
!= NB_EV_APPLY
)
263 area
= nb_running_get_entry(dnode
, NULL
, true);
264 attached
= yang_dnode_get_bool(dnode
, NULL
);
265 isis_area_attached_bit_set(area
, attached
);
271 * XPath: /frr-isisd:isis/instance/overload
273 int isis_instance_overload_modify(enum nb_event event
,
274 const struct lyd_node
*dnode
,
275 union nb_resource
*resource
)
277 struct isis_area
*area
;
280 if (event
!= NB_EV_APPLY
)
283 area
= nb_running_get_entry(dnode
, NULL
, true);
284 overload
= yang_dnode_get_bool(dnode
, NULL
);
285 isis_area_overload_bit_set(area
, overload
);
291 * XPath: /frr-isisd:isis/instance/metric-style
293 int isis_instance_metric_style_modify(enum nb_event event
,
294 const struct lyd_node
*dnode
,
295 union nb_resource
*resource
)
297 struct isis_area
*area
;
298 bool old_metric
, new_metric
;
299 enum isis_metric_style metric_style
= yang_dnode_get_enum(dnode
, NULL
);
301 if (event
!= NB_EV_APPLY
)
304 area
= nb_running_get_entry(dnode
, NULL
, true);
305 old_metric
= (metric_style
== ISIS_WIDE_METRIC
) ? false : true;
306 new_metric
= (metric_style
== ISIS_NARROW_METRIC
) ? false : true;
307 isis_area_metricstyle_set(area
, old_metric
, new_metric
);
313 * XPath: /frr-isisd:isis/instance/purge-originator
315 int isis_instance_purge_originator_modify(enum nb_event event
,
316 const struct lyd_node
*dnode
,
317 union nb_resource
*resource
)
319 struct isis_area
*area
;
321 if (event
!= NB_EV_APPLY
)
324 area
= nb_running_get_entry(dnode
, NULL
, true);
325 area
->purge_originator
= yang_dnode_get_bool(dnode
, NULL
);
331 * XPath: /frr-isisd:isis/instance/lsp/mtu
333 int isis_instance_lsp_mtu_modify(enum nb_event event
,
334 const struct lyd_node
*dnode
,
335 union nb_resource
*resource
)
337 struct listnode
*node
;
338 struct isis_circuit
*circuit
;
339 uint16_t lsp_mtu
= yang_dnode_get_uint16(dnode
, NULL
);
340 struct isis_area
*area
;
344 area
= nb_running_get_entry(dnode
, NULL
, false);
347 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, node
, circuit
)) {
348 if (circuit
->state
!= C_STATE_INIT
349 && circuit
->state
!= C_STATE_UP
)
351 if (lsp_mtu
> isis_circuit_pdu_size(circuit
)) {
353 EC_LIB_NB_CB_CONFIG_VALIDATE
,
354 "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
355 circuit
->interface
->name
,
356 isis_circuit_pdu_size(circuit
));
357 return NB_ERR_VALIDATION
;
365 area
= nb_running_get_entry(dnode
, NULL
, true);
366 isis_area_lsp_mtu_set(area
, lsp_mtu
);
374 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-1
376 int isis_instance_lsp_refresh_interval_level_1_modify(
377 enum nb_event event
, const struct lyd_node
*dnode
,
378 union nb_resource
*resource
)
380 struct isis_area
*area
;
383 if (event
!= NB_EV_APPLY
)
386 refr_int
= yang_dnode_get_uint16(dnode
, NULL
);
387 area
= nb_running_get_entry(dnode
, NULL
, true);
388 isis_area_lsp_refresh_set(area
, IS_LEVEL_1
, refr_int
);
394 * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-2
396 int isis_instance_lsp_refresh_interval_level_2_modify(
397 enum nb_event event
, const struct lyd_node
*dnode
,
398 union nb_resource
*resource
)
400 struct isis_area
*area
;
403 if (event
!= NB_EV_APPLY
)
406 refr_int
= yang_dnode_get_uint16(dnode
, NULL
);
407 area
= nb_running_get_entry(dnode
, NULL
, true);
408 isis_area_lsp_refresh_set(area
, IS_LEVEL_2
, refr_int
);
414 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-1
416 int isis_instance_lsp_maximum_lifetime_level_1_modify(
417 enum nb_event event
, const struct lyd_node
*dnode
,
418 union nb_resource
*resource
)
420 struct isis_area
*area
;
423 if (event
!= NB_EV_APPLY
)
426 max_lt
= yang_dnode_get_uint16(dnode
, NULL
);
427 area
= nb_running_get_entry(dnode
, NULL
, true);
428 isis_area_max_lsp_lifetime_set(area
, IS_LEVEL_1
, max_lt
);
434 * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-2
436 int isis_instance_lsp_maximum_lifetime_level_2_modify(
437 enum nb_event event
, const struct lyd_node
*dnode
,
438 union nb_resource
*resource
)
440 struct isis_area
*area
;
443 if (event
!= NB_EV_APPLY
)
446 max_lt
= yang_dnode_get_uint16(dnode
, NULL
);
447 area
= nb_running_get_entry(dnode
, NULL
, true);
448 isis_area_max_lsp_lifetime_set(area
, IS_LEVEL_2
, max_lt
);
454 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-1
456 int isis_instance_lsp_generation_interval_level_1_modify(
457 enum nb_event event
, const struct lyd_node
*dnode
,
458 union nb_resource
*resource
)
460 struct isis_area
*area
;
463 if (event
!= NB_EV_APPLY
)
466 gen_int
= yang_dnode_get_uint16(dnode
, NULL
);
467 area
= nb_running_get_entry(dnode
, NULL
, true);
468 area
->lsp_gen_interval
[0] = gen_int
;
474 * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-2
476 int isis_instance_lsp_generation_interval_level_2_modify(
477 enum nb_event event
, const struct lyd_node
*dnode
,
478 union nb_resource
*resource
)
480 struct isis_area
*area
;
483 if (event
!= NB_EV_APPLY
)
486 gen_int
= yang_dnode_get_uint16(dnode
, NULL
);
487 area
= nb_running_get_entry(dnode
, NULL
, true);
488 area
->lsp_gen_interval
[1] = gen_int
;
494 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
496 void ietf_backoff_delay_apply_finish(const struct lyd_node
*dnode
)
498 long init_delay
= yang_dnode_get_uint16(dnode
, "./init-delay");
499 long short_delay
= yang_dnode_get_uint16(dnode
, "./short-delay");
500 long long_delay
= yang_dnode_get_uint16(dnode
, "./long-delay");
501 long holddown
= yang_dnode_get_uint16(dnode
, "./hold-down");
502 long timetolearn
= yang_dnode_get_uint16(dnode
, "./time-to-learn");
503 struct isis_area
*area
= nb_running_get_entry(dnode
, NULL
, true);
504 size_t bufsiz
= strlen(area
->area_tag
) + sizeof("IS-IS Lx");
505 char *buf
= XCALLOC(MTYPE_TMP
, bufsiz
);
507 snprintf(buf
, bufsiz
, "IS-IS %s L1", area
->area_tag
);
508 spf_backoff_free(area
->spf_delay_ietf
[0]);
509 area
->spf_delay_ietf
[0] =
510 spf_backoff_new(master
, buf
, init_delay
, short_delay
,
511 long_delay
, holddown
, timetolearn
);
513 snprintf(buf
, bufsiz
, "IS-IS %s L2", area
->area_tag
);
514 spf_backoff_free(area
->spf_delay_ietf
[1]);
515 area
->spf_delay_ietf
[1] =
516 spf_backoff_new(master
, buf
, init_delay
, short_delay
,
517 long_delay
, holddown
, timetolearn
);
519 XFREE(MTYPE_TMP
, buf
);
522 int isis_instance_spf_ietf_backoff_delay_create(enum nb_event event
,
523 const struct lyd_node
*dnode
,
524 union nb_resource
*resource
)
526 /* All the work is done in the apply_finish */
530 int isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event
,
531 const struct lyd_node
*dnode
)
533 struct isis_area
*area
;
535 if (event
!= NB_EV_APPLY
)
538 area
= nb_running_get_entry(dnode
, NULL
, true);
539 spf_backoff_free(area
->spf_delay_ietf
[0]);
540 spf_backoff_free(area
->spf_delay_ietf
[1]);
541 area
->spf_delay_ietf
[0] = NULL
;
542 area
->spf_delay_ietf
[1] = NULL
;
548 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
550 int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
551 enum nb_event event
, const struct lyd_node
*dnode
,
552 union nb_resource
*resource
)
554 /* All the work is done in the apply_finish */
559 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
561 int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
562 enum nb_event event
, const struct lyd_node
*dnode
,
563 union nb_resource
*resource
)
565 /* All the work is done in the apply_finish */
570 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
572 int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
573 enum nb_event event
, const struct lyd_node
*dnode
,
574 union nb_resource
*resource
)
576 /* All the work is done in the apply_finish */
581 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
583 int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
584 enum nb_event event
, const struct lyd_node
*dnode
,
585 union nb_resource
*resource
)
587 /* All the work is done in the apply_finish */
592 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
594 int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
595 enum nb_event event
, const struct lyd_node
*dnode
,
596 union nb_resource
*resource
)
598 /* All the work is done in the apply_finish */
603 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
605 int isis_instance_spf_minimum_interval_level_1_modify(
606 enum nb_event event
, const struct lyd_node
*dnode
,
607 union nb_resource
*resource
)
609 struct isis_area
*area
;
611 if (event
!= NB_EV_APPLY
)
614 area
= nb_running_get_entry(dnode
, NULL
, true);
615 area
->min_spf_interval
[0] = yang_dnode_get_uint16(dnode
, NULL
);
621 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
623 int isis_instance_spf_minimum_interval_level_2_modify(
624 enum nb_event event
, const struct lyd_node
*dnode
,
625 union nb_resource
*resource
)
627 struct isis_area
*area
;
629 if (event
!= NB_EV_APPLY
)
632 area
= nb_running_get_entry(dnode
, NULL
, true);
633 area
->min_spf_interval
[1] = yang_dnode_get_uint16(dnode
, NULL
);
639 * XPath: /frr-isisd:isis/instance/area-password
641 void area_password_apply_finish(const struct lyd_node
*dnode
)
643 const char *password
= yang_dnode_get_string(dnode
, "./password");
644 struct isis_area
*area
= nb_running_get_entry(dnode
, NULL
, true);
645 int pass_type
= yang_dnode_get_enum(dnode
, "./password-type");
646 uint8_t snp_auth
= yang_dnode_get_enum(dnode
, "./authenticate-snp");
649 case ISIS_PASSWD_TYPE_CLEARTXT
:
650 isis_area_passwd_cleartext_set(area
, IS_LEVEL_1
, password
,
653 case ISIS_PASSWD_TYPE_HMAC_MD5
:
654 isis_area_passwd_hmac_md5_set(area
, IS_LEVEL_1
, password
,
660 int isis_instance_area_password_create(enum nb_event event
,
661 const struct lyd_node
*dnode
,
662 union nb_resource
*resource
)
664 /* actual setting is done in apply_finish */
668 int isis_instance_area_password_destroy(enum nb_event event
,
669 const struct lyd_node
*dnode
)
671 struct isis_area
*area
;
673 if (event
!= NB_EV_APPLY
)
676 area
= nb_running_get_entry(dnode
, NULL
, true);
677 isis_area_passwd_unset(area
, IS_LEVEL_1
);
683 * XPath: /frr-isisd:isis/instance/area-password/password
685 int isis_instance_area_password_password_modify(enum nb_event event
,
686 const struct lyd_node
*dnode
,
687 union nb_resource
*resource
)
689 /* actual setting is done in apply_finish */
694 * XPath: /frr-isisd:isis/instance/area-password/password-type
696 int isis_instance_area_password_password_type_modify(
697 enum nb_event event
, const struct lyd_node
*dnode
,
698 union nb_resource
*resource
)
700 /* actual setting is done in apply_finish */
705 * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
707 int isis_instance_area_password_authenticate_snp_modify(
708 enum nb_event event
, const struct lyd_node
*dnode
,
709 union nb_resource
*resource
)
711 /* actual setting is done in apply_finish */
716 * XPath: /frr-isisd:isis/instance/domain-password
718 void domain_password_apply_finish(const struct lyd_node
*dnode
)
720 const char *password
= yang_dnode_get_string(dnode
, "./password");
721 struct isis_area
*area
= nb_running_get_entry(dnode
, NULL
, true);
722 int pass_type
= yang_dnode_get_enum(dnode
, "./password-type");
723 uint8_t snp_auth
= yang_dnode_get_enum(dnode
, "./authenticate-snp");
726 case ISIS_PASSWD_TYPE_CLEARTXT
:
727 isis_area_passwd_cleartext_set(area
, IS_LEVEL_2
, password
,
730 case ISIS_PASSWD_TYPE_HMAC_MD5
:
731 isis_area_passwd_hmac_md5_set(area
, IS_LEVEL_2
, password
,
737 int isis_instance_domain_password_create(enum nb_event event
,
738 const struct lyd_node
*dnode
,
739 union nb_resource
*resource
)
741 /* actual setting is done in apply_finish */
745 int isis_instance_domain_password_destroy(enum nb_event event
,
746 const struct lyd_node
*dnode
)
748 struct isis_area
*area
;
750 if (event
!= NB_EV_APPLY
)
753 area
= nb_running_get_entry(dnode
, NULL
, true);
754 isis_area_passwd_unset(area
, IS_LEVEL_2
);
760 * XPath: /frr-isisd:isis/instance/domain-password/password
762 int isis_instance_domain_password_password_modify(enum nb_event event
,
763 const struct lyd_node
*dnode
,
764 union nb_resource
*resource
)
766 /* actual setting is done in apply_finish */
771 * XPath: /frr-isisd:isis/instance/domain-password/password-type
773 int isis_instance_domain_password_password_type_modify(
774 enum nb_event event
, const struct lyd_node
*dnode
,
775 union nb_resource
*resource
)
777 /* actual setting is done in apply_finish */
782 * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
784 int isis_instance_domain_password_authenticate_snp_modify(
785 enum nb_event event
, const struct lyd_node
*dnode
,
786 union nb_resource
*resource
)
788 /* actual setting is done in apply_finish */
793 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
795 void default_info_origin_apply_finish(const struct lyd_node
*dnode
, int family
)
797 int originate_type
= DEFAULT_ORIGINATE
;
798 unsigned long metric
= 0;
799 const char *routemap
= NULL
;
800 struct isis_area
*area
= nb_running_get_entry(dnode
, NULL
, true);
801 int level
= yang_dnode_get_enum(dnode
, "./level");
803 if (yang_dnode_get_bool(dnode
, "./always")) {
804 originate_type
= DEFAULT_ORIGINATE_ALWAYS
;
805 } else if (family
== AF_INET6
) {
807 "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
811 if (yang_dnode_exists(dnode
, "./metric"))
812 metric
= yang_dnode_get_uint32(dnode
, "./metric");
813 if (yang_dnode_exists(dnode
, "./route-map"))
814 routemap
= yang_dnode_get_string(dnode
, "./route-map");
816 isis_redist_set(area
, level
, family
, DEFAULT_ROUTE
, metric
, routemap
,
820 void default_info_origin_ipv4_apply_finish(const struct lyd_node
*dnode
)
822 default_info_origin_apply_finish(dnode
, AF_INET
);
825 void default_info_origin_ipv6_apply_finish(const struct lyd_node
*dnode
)
827 default_info_origin_apply_finish(dnode
, AF_INET6
);
830 int isis_instance_default_information_originate_ipv4_create(
831 enum nb_event event
, const struct lyd_node
*dnode
,
832 union nb_resource
*resource
)
834 /* It's all done by default_info_origin_apply_finish */
838 int isis_instance_default_information_originate_ipv4_destroy(
839 enum nb_event event
, const struct lyd_node
*dnode
)
841 struct isis_area
*area
;
844 if (event
!= NB_EV_APPLY
)
847 area
= nb_running_get_entry(dnode
, NULL
, true);
848 level
= yang_dnode_get_enum(dnode
, "./level");
849 isis_redist_unset(area
, level
, AF_INET
, DEFAULT_ROUTE
);
855 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
857 int isis_instance_default_information_originate_ipv4_always_modify(
858 enum nb_event event
, const struct lyd_node
*dnode
,
859 union nb_resource
*resource
)
861 /* It's all done by default_info_origin_apply_finish */
866 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
868 int isis_instance_default_information_originate_ipv4_route_map_modify(
869 enum nb_event event
, const struct lyd_node
*dnode
,
870 union nb_resource
*resource
)
872 /* It's all done by default_info_origin_apply_finish */
876 int isis_instance_default_information_originate_ipv4_route_map_destroy(
877 enum nb_event event
, const struct lyd_node
*dnode
)
879 /* It's all done by default_info_origin_apply_finish */
884 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
886 int isis_instance_default_information_originate_ipv4_metric_modify(
887 enum nb_event event
, const struct lyd_node
*dnode
,
888 union nb_resource
*resource
)
890 /* It's all done by default_info_origin_apply_finish */
895 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
897 int isis_instance_default_information_originate_ipv6_create(
898 enum nb_event event
, const struct lyd_node
*dnode
,
899 union nb_resource
*resource
)
901 /* It's all done by default_info_origin_apply_finish */
905 int isis_instance_default_information_originate_ipv6_destroy(
906 enum nb_event event
, const struct lyd_node
*dnode
)
908 struct isis_area
*area
;
911 if (event
!= NB_EV_APPLY
)
914 area
= nb_running_get_entry(dnode
, NULL
, true);
915 level
= yang_dnode_get_enum(dnode
, "./level");
916 isis_redist_unset(area
, level
, AF_INET6
, DEFAULT_ROUTE
);
922 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
924 int isis_instance_default_information_originate_ipv6_always_modify(
925 enum nb_event event
, const struct lyd_node
*dnode
,
926 union nb_resource
*resource
)
928 /* It's all done by default_info_origin_apply_finish */
933 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
935 int isis_instance_default_information_originate_ipv6_route_map_modify(
936 enum nb_event event
, const struct lyd_node
*dnode
,
937 union nb_resource
*resource
)
939 /* It's all done by default_info_origin_apply_finish */
943 int isis_instance_default_information_originate_ipv6_route_map_destroy(
944 enum nb_event event
, const struct lyd_node
*dnode
)
946 /* It's all done by default_info_origin_apply_finish */
951 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
953 int isis_instance_default_information_originate_ipv6_metric_modify(
954 enum nb_event event
, const struct lyd_node
*dnode
,
955 union nb_resource
*resource
)
957 /* It's all done by default_info_origin_apply_finish */
962 * XPath: /frr-isisd:isis/instance/redistribute/ipv4
964 void redistribute_apply_finish(const struct lyd_node
*dnode
, int family
)
966 assert(family
== AF_INET
|| family
== AF_INET6
);
968 unsigned long metric
= 0;
969 const char *routemap
= NULL
;
970 struct isis_area
*area
;
972 type
= yang_dnode_get_enum(dnode
, "./protocol");
973 level
= yang_dnode_get_enum(dnode
, "./level");
974 area
= nb_running_get_entry(dnode
, NULL
, true);
976 if (yang_dnode_exists(dnode
, "./metric"))
977 metric
= yang_dnode_get_uint32(dnode
, "./metric");
978 if (yang_dnode_exists(dnode
, "./route-map"))
979 routemap
= yang_dnode_get_string(dnode
, "./route-map");
981 isis_redist_set(area
, level
, family
, type
, metric
, routemap
, 0);
984 void redistribute_ipv4_apply_finish(const struct lyd_node
*dnode
)
986 redistribute_apply_finish(dnode
, AF_INET
);
989 void redistribute_ipv6_apply_finish(const struct lyd_node
*dnode
)
991 redistribute_apply_finish(dnode
, AF_INET6
);
994 int isis_instance_redistribute_ipv4_create(enum nb_event event
,
995 const struct lyd_node
*dnode
,
996 union nb_resource
*resource
)
998 /* It's all done by redistribute_apply_finish */
1002 int isis_instance_redistribute_ipv4_destroy(enum nb_event event
,
1003 const struct lyd_node
*dnode
)
1005 struct isis_area
*area
;
1008 if (event
!= NB_EV_APPLY
)
1011 area
= nb_running_get_entry(dnode
, NULL
, true);
1012 level
= yang_dnode_get_enum(dnode
, "./level");
1013 type
= yang_dnode_get_enum(dnode
, "./protocol");
1014 isis_redist_unset(area
, level
, AF_INET
, type
);
1020 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
1022 int isis_instance_redistribute_ipv4_route_map_modify(
1023 enum nb_event event
, const struct lyd_node
*dnode
,
1024 union nb_resource
*resource
)
1026 /* It's all done by redistribute_apply_finish */
1030 int isis_instance_redistribute_ipv4_route_map_destroy(
1031 enum nb_event event
, const struct lyd_node
*dnode
)
1033 /* It's all done by redistribute_apply_finish */
1038 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
1040 int isis_instance_redistribute_ipv4_metric_modify(enum nb_event event
,
1041 const struct lyd_node
*dnode
,
1042 union nb_resource
*resource
)
1044 /* It's all done by redistribute_apply_finish */
1049 * XPath: /frr-isisd:isis/instance/redistribute/ipv6
1051 int isis_instance_redistribute_ipv6_create(enum nb_event event
,
1052 const struct lyd_node
*dnode
,
1053 union nb_resource
*resource
)
1055 /* It's all done by redistribute_apply_finish */
1059 int isis_instance_redistribute_ipv6_destroy(enum nb_event event
,
1060 const struct lyd_node
*dnode
)
1062 struct isis_area
*area
;
1065 if (event
!= NB_EV_APPLY
)
1068 area
= nb_running_get_entry(dnode
, NULL
, true);
1069 level
= yang_dnode_get_enum(dnode
, "./level");
1070 type
= yang_dnode_get_enum(dnode
, "./protocol");
1071 isis_redist_unset(area
, level
, AF_INET6
, type
);
1077 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
1079 int isis_instance_redistribute_ipv6_route_map_modify(
1080 enum nb_event event
, const struct lyd_node
*dnode
,
1081 union nb_resource
*resource
)
1083 /* It's all done by redistribute_apply_finish */
1087 int isis_instance_redistribute_ipv6_route_map_destroy(
1088 enum nb_event event
, const struct lyd_node
*dnode
)
1090 /* It's all done by redistribute_apply_finish */
1095 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
1097 int isis_instance_redistribute_ipv6_metric_modify(enum nb_event event
,
1098 const struct lyd_node
*dnode
,
1099 union nb_resource
*resource
)
1101 /* It's all done by redistribute_apply_finish */
1106 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
1108 static int isis_multi_topology_common(enum nb_event event
,
1109 const struct lyd_node
*dnode
,
1110 const char *topology
, bool create
)
1112 struct isis_area
*area
;
1113 struct isis_area_mt_setting
*setting
;
1114 uint16_t mtid
= isis_str2mtid(topology
);
1117 case NB_EV_VALIDATE
:
1118 if (mtid
== (uint16_t)-1) {
1119 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1120 "Unknown topology %s", topology
);
1121 return NB_ERR_VALIDATION
;
1128 area
= nb_running_get_entry(dnode
, NULL
, true);
1129 setting
= area_get_mt_setting(area
, mtid
);
1130 setting
->enabled
= create
;
1131 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 0);
1138 static int isis_multi_topology_overload_common(enum nb_event event
,
1139 const struct lyd_node
*dnode
,
1140 const char *topology
)
1142 struct isis_area
*area
;
1143 struct isis_area_mt_setting
*setting
;
1144 uint16_t mtid
= isis_str2mtid(topology
);
1146 /* validation is done in isis_multi_topology_common */
1147 if (event
!= NB_EV_APPLY
)
1150 area
= nb_running_get_entry(dnode
, NULL
, true);
1151 setting
= area_get_mt_setting(area
, mtid
);
1152 setting
->overload
= yang_dnode_get_bool(dnode
, NULL
);
1153 if (setting
->enabled
)
1154 lsp_regenerate_schedule(area
, IS_LEVEL_1
| IS_LEVEL_2
, 0);
1159 int isis_instance_multi_topology_ipv4_multicast_create(
1160 enum nb_event event
, const struct lyd_node
*dnode
,
1161 union nb_resource
*resource
)
1163 return isis_multi_topology_common(event
, dnode
, "ipv4-multicast", true);
1166 int isis_instance_multi_topology_ipv4_multicast_destroy(
1167 enum nb_event event
, const struct lyd_node
*dnode
)
1169 return isis_multi_topology_common(event
, dnode
, "ipv4-multicast",
1174 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
1176 int isis_instance_multi_topology_ipv4_multicast_overload_modify(
1177 enum nb_event event
, const struct lyd_node
*dnode
,
1178 union nb_resource
*resource
)
1180 return isis_multi_topology_overload_common(event
, dnode
,
1185 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
1187 int isis_instance_multi_topology_ipv4_management_create(
1188 enum nb_event event
, const struct lyd_node
*dnode
,
1189 union nb_resource
*resource
)
1191 return isis_multi_topology_common(event
, dnode
, "ipv4-mgmt", true);
1194 int isis_instance_multi_topology_ipv4_management_destroy(
1195 enum nb_event event
, const struct lyd_node
*dnode
)
1197 return isis_multi_topology_common(event
, dnode
, "ipv4-mgmt", false);
1201 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
1203 int isis_instance_multi_topology_ipv4_management_overload_modify(
1204 enum nb_event event
, const struct lyd_node
*dnode
,
1205 union nb_resource
*resource
)
1207 return isis_multi_topology_overload_common(event
, dnode
, "ipv4-mgmt");
1211 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
1213 int isis_instance_multi_topology_ipv6_unicast_create(
1214 enum nb_event event
, const struct lyd_node
*dnode
,
1215 union nb_resource
*resource
)
1217 return isis_multi_topology_common(event
, dnode
, "ipv6-unicast", true);
1220 int isis_instance_multi_topology_ipv6_unicast_destroy(
1221 enum nb_event event
, const struct lyd_node
*dnode
)
1223 return isis_multi_topology_common(event
, dnode
, "ipv6-unicast", false);
1227 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
1229 int isis_instance_multi_topology_ipv6_unicast_overload_modify(
1230 enum nb_event event
, const struct lyd_node
*dnode
,
1231 union nb_resource
*resource
)
1233 return isis_multi_topology_overload_common(event
, dnode
,
1238 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
1240 int isis_instance_multi_topology_ipv6_multicast_create(
1241 enum nb_event event
, const struct lyd_node
*dnode
,
1242 union nb_resource
*resource
)
1244 return isis_multi_topology_common(event
, dnode
, "ipv6-multicast", true);
1247 int isis_instance_multi_topology_ipv6_multicast_destroy(
1248 enum nb_event event
, const struct lyd_node
*dnode
)
1250 return isis_multi_topology_common(event
, dnode
, "ipv6-multicast",
1255 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
1257 int isis_instance_multi_topology_ipv6_multicast_overload_modify(
1258 enum nb_event event
, const struct lyd_node
*dnode
,
1259 union nb_resource
*resource
)
1261 return isis_multi_topology_overload_common(event
, dnode
,
1266 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
1268 int isis_instance_multi_topology_ipv6_management_create(
1269 enum nb_event event
, const struct lyd_node
*dnode
,
1270 union nb_resource
*resource
)
1272 return isis_multi_topology_common(event
, dnode
, "ipv6-mgmt", true);
1275 int isis_instance_multi_topology_ipv6_management_destroy(
1276 enum nb_event event
, const struct lyd_node
*dnode
)
1278 return isis_multi_topology_common(event
, dnode
, "ipv6-mgmt", false);
1282 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
1284 int isis_instance_multi_topology_ipv6_management_overload_modify(
1285 enum nb_event event
, const struct lyd_node
*dnode
,
1286 union nb_resource
*resource
)
1288 return isis_multi_topology_overload_common(event
, dnode
, "ipv6-mgmt");
1292 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
1294 int isis_instance_multi_topology_ipv6_dstsrc_create(
1295 enum nb_event event
, const struct lyd_node
*dnode
,
1296 union nb_resource
*resource
)
1298 return isis_multi_topology_common(event
, dnode
, "ipv6-dstsrc", true);
1301 int isis_instance_multi_topology_ipv6_dstsrc_destroy(
1302 enum nb_event event
, const struct lyd_node
*dnode
)
1304 return isis_multi_topology_common(event
, dnode
, "ipv6-dstsrc", false);
1308 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
1310 int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
1311 enum nb_event event
, const struct lyd_node
*dnode
,
1312 union nb_resource
*resource
)
1314 return isis_multi_topology_overload_common(event
, dnode
, "ipv6-dstsrc");
1318 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1320 int isis_instance_log_adjacency_changes_modify(enum nb_event event
,
1321 const struct lyd_node
*dnode
,
1322 union nb_resource
*resource
)
1324 struct isis_area
*area
;
1325 bool log
= yang_dnode_get_bool(dnode
, NULL
);
1327 if (event
!= NB_EV_APPLY
)
1330 area
= nb_running_get_entry(dnode
, NULL
, true);
1331 area
->log_adj_changes
= log
? 1 : 0;
1337 * XPath: /frr-isisd:isis/instance/mpls-te
1339 int isis_instance_mpls_te_create(enum nb_event event
,
1340 const struct lyd_node
*dnode
,
1341 union nb_resource
*resource
)
1343 struct listnode
*node
;
1344 struct isis_area
*area
;
1345 struct isis_circuit
*circuit
;
1347 if (event
!= NB_EV_APPLY
)
1350 area
= nb_running_get_entry(dnode
, NULL
, true);
1351 if (area
->mta
== NULL
) {
1353 struct mpls_te_area
*new;
1355 zlog_debug("ISIS-TE(%s): Initialize MPLS Traffic Engineering",
1358 new = XCALLOC(MTYPE_ISIS_MPLS_TE
, sizeof(struct mpls_te_area
));
1360 /* Initialize MPLS_TE structure */
1361 new->status
= enable
;
1363 new->inter_as
= off
;
1364 new->interas_areaid
.s_addr
= 0;
1365 new->router_id
.s_addr
= 0;
1369 area
->mta
->status
= enable
;
1372 /* Update Extended TLVs according to Interface link parameters */
1373 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, node
, circuit
))
1374 isis_link_params_update(circuit
, circuit
->interface
);
1376 /* Reoriginate STD_TE & GMPLS circuits */
1377 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1382 int isis_instance_mpls_te_destroy(enum nb_event event
,
1383 const struct lyd_node
*dnode
)
1385 struct listnode
*node
;
1386 struct isis_area
*area
;
1387 struct isis_circuit
*circuit
;
1389 if (event
!= NB_EV_APPLY
)
1392 area
= nb_running_get_entry(dnode
, NULL
, true);
1393 if (IS_MPLS_TE(area
->mta
))
1394 area
->mta
->status
= disable
;
1398 /* Flush LSP if circuit engage */
1399 for (ALL_LIST_ELEMENTS_RO(area
->circuit_list
, node
, circuit
)) {
1400 if (!IS_EXT_TE(circuit
->ext
))
1403 /* disable MPLS_TE Circuit keeping SR one's */
1404 if (IS_SUBTLV(circuit
->ext
, EXT_ADJ_SID
))
1405 circuit
->ext
->status
= EXT_ADJ_SID
;
1406 else if (IS_SUBTLV(circuit
->ext
, EXT_LAN_ADJ_SID
))
1407 circuit
->ext
->status
= EXT_LAN_ADJ_SID
;
1409 circuit
->ext
->status
= 0;
1412 /* Reoriginate STD_TE & GMPLS circuits */
1413 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1415 zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
1422 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
1424 int isis_instance_mpls_te_router_address_modify(enum nb_event event
,
1425 const struct lyd_node
*dnode
,
1426 union nb_resource
*resource
)
1428 struct in_addr value
;
1429 struct isis_area
*area
;
1431 if (event
!= NB_EV_APPLY
)
1434 area
= nb_running_get_entry(dnode
, NULL
, true);
1435 /* only proceed if MPLS-TE is enabled */
1436 if (!IS_MPLS_TE(area
->mta
))
1439 /* Update Area Router ID */
1440 yang_dnode_get_ipv4(&value
, dnode
, NULL
);
1441 area
->mta
->router_id
.s_addr
= value
.s_addr
;
1443 /* And re-schedule LSP update */
1444 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1449 int isis_instance_mpls_te_router_address_destroy(enum nb_event event
,
1450 const struct lyd_node
*dnode
)
1452 struct isis_area
*area
;
1454 if (event
!= NB_EV_APPLY
)
1457 area
= nb_running_get_entry(dnode
, NULL
, true);
1458 /* only proceed if MPLS-TE is enabled */
1459 if (!IS_MPLS_TE(area
->mta
))
1462 /* Reset Area Router ID */
1463 area
->mta
->router_id
.s_addr
= INADDR_ANY
;
1465 /* And re-schedule LSP update */
1466 lsp_regenerate_schedule(area
, area
->is_type
, 0);
1472 * XPath: /frr-interface:lib/interface/frr-isisd:isis
1474 int lib_interface_isis_create(enum nb_event event
, const struct lyd_node
*dnode
,
1475 union nb_resource
*resource
)
1477 struct isis_area
*area
;
1478 struct interface
*ifp
;
1479 struct isis_circuit
*circuit
;
1480 const char *area_tag
= yang_dnode_get_string(dnode
, "./area-tag");
1481 uint32_t min_mtu
, actual_mtu
;
1487 case NB_EV_VALIDATE
:
1488 /* check if interface mtu is sufficient. If the area has not
1489 * been created yet, assume default MTU for the area
1491 ifp
= nb_running_get_entry(dnode
, NULL
, false);
1492 /* zebra might not know yet about the MTU - nothing we can do */
1493 if (!ifp
|| ifp
->mtu
== 0)
1496 if_is_broadcast(ifp
) ? ifp
->mtu
- LLC_LEN
: ifp
->mtu
;
1497 area
= isis_area_lookup(area_tag
);
1499 min_mtu
= area
->lsp_mtu
;
1502 min_mtu
= yang_get_default_uint16(
1503 "/frr-isisd:isis/instance/lsp/mtu");
1505 min_mtu
= DEFAULT_LSP_MTU
;
1506 #endif /* ifndef FABRICD */
1507 if (actual_mtu
< min_mtu
) {
1508 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1509 "Interface %s has MTU %" PRIu32
1510 ", minimum MTU for the area is %" PRIu32
"",
1511 ifp
->name
, actual_mtu
, min_mtu
);
1512 return NB_ERR_VALIDATION
;
1516 area
= isis_area_lookup(area_tag
);
1517 /* The area should have already be created. We are
1518 * setting the priority of the global isis area creation
1519 * slightly lower, so it should be executed first, but I
1520 * cannot rely on that so here I have to check.
1524 EC_LIB_NB_CB_CONFIG_APPLY
,
1525 "%s: attempt to create circuit for area %s before the area has been created",
1526 __func__
, area_tag
);
1530 ifp
= nb_running_get_entry(dnode
, NULL
, true);
1531 circuit
= isis_circuit_create(area
, ifp
);
1533 && (circuit
->state
== C_STATE_CONF
1534 || circuit
->state
== C_STATE_UP
));
1535 nb_running_set_entry(dnode
, circuit
);
1542 int lib_interface_isis_destroy(enum nb_event event
,
1543 const struct lyd_node
*dnode
)
1545 struct isis_circuit
*circuit
;
1547 if (event
!= NB_EV_APPLY
)
1550 circuit
= nb_running_unset_entry(dnode
);
1552 return NB_ERR_INCONSISTENCY
;
1554 /* disable both AFs for this circuit. this will also update the
1555 * CSM state by sending an ISIS_DISABLED signal. If there is no
1556 * area associated to the circuit there is nothing to do
1559 isis_circuit_af_set(circuit
, false, false);
1564 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1566 int lib_interface_isis_area_tag_modify(enum nb_event event
,
1567 const struct lyd_node
*dnode
,
1568 union nb_resource
*resource
)
1570 struct isis_circuit
*circuit
;
1571 struct interface
*ifp
;
1573 const char *area_tag
, *ifname
, *vrfname
;
1575 if (event
== NB_EV_VALIDATE
) {
1576 /* libyang doesn't like relative paths across module boundaries
1578 ifname
= yang_dnode_get_string(dnode
->parent
->parent
, "./name");
1579 vrfname
= yang_dnode_get_string(dnode
->parent
->parent
, "./vrf");
1580 vrf
= vrf_lookup_by_name(vrfname
);
1582 ifp
= if_lookup_by_name(ifname
, vrf
->vrf_id
);
1585 circuit
= circuit_lookup_by_ifp(ifp
, isis
->init_circ_list
);
1586 area_tag
= yang_dnode_get_string(dnode
, NULL
);
1587 if (circuit
&& circuit
->area
&& circuit
->area
->area_tag
1588 && strcmp(circuit
->area
->area_tag
, area_tag
)) {
1589 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1590 "ISIS circuit is already defined on %s",
1591 circuit
->area
->area_tag
);
1592 return NB_ERR_VALIDATION
;
1600 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1602 int lib_interface_isis_circuit_type_modify(enum nb_event event
,
1603 const struct lyd_node
*dnode
,
1604 union nb_resource
*resource
)
1606 int circ_type
= yang_dnode_get_enum(dnode
, NULL
);
1607 struct isis_circuit
*circuit
;
1608 struct interface
*ifp
;
1610 const char *ifname
, *vrfname
;
1613 case NB_EV_VALIDATE
:
1614 /* libyang doesn't like relative paths across module boundaries
1616 ifname
= yang_dnode_get_string(dnode
->parent
->parent
, "./name");
1617 vrfname
= yang_dnode_get_string(dnode
->parent
->parent
, "./vrf");
1618 vrf
= vrf_lookup_by_name(vrfname
);
1620 ifp
= if_lookup_by_name(ifname
, vrf
->vrf_id
);
1623 circuit
= circuit_lookup_by_ifp(ifp
, isis
->init_circ_list
);
1624 if (circuit
&& circuit
->state
== C_STATE_UP
1625 && circuit
->area
->is_type
!= IS_LEVEL_1_AND_2
1626 && circuit
->area
->is_type
!= circ_type
) {
1627 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1628 "Invalid circuit level for area %s",
1629 circuit
->area
->area_tag
);
1630 return NB_ERR_VALIDATION
;
1637 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1638 isis_circuit_is_type_set(circuit
, circ_type
);
1646 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1648 int lib_interface_isis_ipv4_routing_modify(enum nb_event event
,
1649 const struct lyd_node
*dnode
,
1650 union nb_resource
*resource
)
1653 struct isis_circuit
*circuit
;
1655 if (event
!= NB_EV_APPLY
)
1658 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1659 ipv4
= yang_dnode_get_bool(dnode
, NULL
);
1660 ipv6
= yang_dnode_get_bool(dnode
, "../ipv6-routing");
1661 isis_circuit_af_set(circuit
, ipv4
, ipv6
);
1667 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1669 int lib_interface_isis_ipv6_routing_modify(enum nb_event event
,
1670 const struct lyd_node
*dnode
,
1671 union nb_resource
*resource
)
1674 struct isis_circuit
*circuit
;
1676 if (event
!= NB_EV_APPLY
)
1679 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1680 ipv4
= yang_dnode_exists(dnode
, "../ipv4-routing");
1681 ipv6
= yang_dnode_get_bool(dnode
, NULL
);
1682 isis_circuit_af_set(circuit
, ipv4
, ipv6
);
1688 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
1690 int lib_interface_isis_bfd_monitoring_modify(enum nb_event event
,
1691 const struct lyd_node
*dnode
,
1692 union nb_resource
*resource
)
1694 struct isis_circuit
*circuit
;
1695 bool bfd_monitoring
;
1697 if (event
!= NB_EV_APPLY
)
1700 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1701 bfd_monitoring
= yang_dnode_get_bool(dnode
, NULL
);
1703 if (bfd_monitoring
) {
1704 isis_bfd_circuit_param_set(circuit
, BFD_DEF_MIN_RX
,
1705 BFD_DEF_MIN_TX
, BFD_DEF_DETECT_MULT
,
1708 isis_bfd_circuit_cmd(circuit
, ZEBRA_BFD_DEST_DEREGISTER
);
1709 bfd_info_free(&circuit
->bfd_info
);
1716 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1718 int lib_interface_isis_csnp_interval_level_1_modify(
1719 enum nb_event event
, const struct lyd_node
*dnode
,
1720 union nb_resource
*resource
)
1722 struct isis_circuit
*circuit
;
1724 if (event
!= NB_EV_APPLY
)
1727 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1728 circuit
->csnp_interval
[0] = yang_dnode_get_uint16(dnode
, NULL
);
1734 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1736 int lib_interface_isis_csnp_interval_level_2_modify(
1737 enum nb_event event
, const struct lyd_node
*dnode
,
1738 union nb_resource
*resource
)
1740 struct isis_circuit
*circuit
;
1742 if (event
!= NB_EV_APPLY
)
1745 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1746 circuit
->csnp_interval
[1] = yang_dnode_get_uint16(dnode
, NULL
);
1752 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1754 int lib_interface_isis_psnp_interval_level_1_modify(
1755 enum nb_event event
, const struct lyd_node
*dnode
,
1756 union nb_resource
*resource
)
1758 struct isis_circuit
*circuit
;
1760 if (event
!= NB_EV_APPLY
)
1763 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1764 circuit
->psnp_interval
[0] = yang_dnode_get_uint16(dnode
, NULL
);
1770 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1772 int lib_interface_isis_psnp_interval_level_2_modify(
1773 enum nb_event event
, const struct lyd_node
*dnode
,
1774 union nb_resource
*resource
)
1776 struct isis_circuit
*circuit
;
1778 if (event
!= NB_EV_APPLY
)
1781 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1782 circuit
->psnp_interval
[1] = yang_dnode_get_uint16(dnode
, NULL
);
1788 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1790 int lib_interface_isis_hello_padding_modify(enum nb_event event
,
1791 const struct lyd_node
*dnode
,
1792 union nb_resource
*resource
)
1794 struct isis_circuit
*circuit
;
1796 if (event
!= NB_EV_APPLY
)
1799 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1800 circuit
->pad_hellos
= yang_dnode_get_bool(dnode
, NULL
);
1806 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1808 int lib_interface_isis_hello_interval_level_1_modify(
1809 enum nb_event event
, const struct lyd_node
*dnode
,
1810 union nb_resource
*resource
)
1812 struct isis_circuit
*circuit
;
1815 if (event
!= NB_EV_APPLY
)
1818 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1819 interval
= yang_dnode_get_uint32(dnode
, NULL
);
1820 circuit
->hello_interval
[0] = interval
;
1826 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1828 int lib_interface_isis_hello_interval_level_2_modify(
1829 enum nb_event event
, const struct lyd_node
*dnode
,
1830 union nb_resource
*resource
)
1832 struct isis_circuit
*circuit
;
1835 if (event
!= NB_EV_APPLY
)
1838 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1839 interval
= yang_dnode_get_uint32(dnode
, NULL
);
1840 circuit
->hello_interval
[1] = interval
;
1846 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
1848 int lib_interface_isis_hello_multiplier_level_1_modify(
1849 enum nb_event event
, const struct lyd_node
*dnode
,
1850 union nb_resource
*resource
)
1852 struct isis_circuit
*circuit
;
1855 if (event
!= NB_EV_APPLY
)
1858 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1859 multi
= yang_dnode_get_uint16(dnode
, NULL
);
1860 circuit
->hello_multiplier
[0] = multi
;
1866 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1868 int lib_interface_isis_hello_multiplier_level_2_modify(
1869 enum nb_event event
, const struct lyd_node
*dnode
,
1870 union nb_resource
*resource
)
1872 struct isis_circuit
*circuit
;
1875 if (event
!= NB_EV_APPLY
)
1878 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1879 multi
= yang_dnode_get_uint16(dnode
, NULL
);
1880 circuit
->hello_multiplier
[1] = multi
;
1886 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1888 int lib_interface_isis_metric_level_1_modify(enum nb_event event
,
1889 const struct lyd_node
*dnode
,
1890 union nb_resource
*resource
)
1892 struct isis_circuit
*circuit
;
1895 if (event
!= NB_EV_APPLY
)
1898 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1899 met
= yang_dnode_get_uint32(dnode
, NULL
);
1900 isis_circuit_metric_set(circuit
, IS_LEVEL_1
, met
);
1906 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1908 int lib_interface_isis_metric_level_2_modify(enum nb_event event
,
1909 const struct lyd_node
*dnode
,
1910 union nb_resource
*resource
)
1912 struct isis_circuit
*circuit
;
1915 if (event
!= NB_EV_APPLY
)
1918 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1919 met
= yang_dnode_get_uint32(dnode
, NULL
);
1920 isis_circuit_metric_set(circuit
, IS_LEVEL_2
, met
);
1926 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
1928 int lib_interface_isis_priority_level_1_modify(enum nb_event event
,
1929 const struct lyd_node
*dnode
,
1930 union nb_resource
*resource
)
1932 struct isis_circuit
*circuit
;
1934 if (event
!= NB_EV_APPLY
)
1937 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1938 circuit
->priority
[0] = yang_dnode_get_uint8(dnode
, NULL
);
1944 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1946 int lib_interface_isis_priority_level_2_modify(enum nb_event event
,
1947 const struct lyd_node
*dnode
,
1948 union nb_resource
*resource
)
1950 struct isis_circuit
*circuit
;
1952 if (event
!= NB_EV_APPLY
)
1955 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1956 circuit
->priority
[1] = yang_dnode_get_uint8(dnode
, NULL
);
1962 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1964 int lib_interface_isis_network_type_modify(enum nb_event event
,
1965 const struct lyd_node
*dnode
,
1966 union nb_resource
*resource
)
1968 struct isis_circuit
*circuit
;
1969 int net_type
= yang_dnode_get_enum(dnode
, NULL
);
1972 case NB_EV_VALIDATE
:
1973 circuit
= nb_running_get_entry(dnode
, NULL
, false);
1976 if (circuit
->circ_type
== CIRCUIT_T_LOOPBACK
) {
1978 EC_LIB_NB_CB_CONFIG_VALIDATE
,
1979 "Cannot change network type on loopback interface");
1980 return NB_ERR_VALIDATION
;
1982 if (net_type
== CIRCUIT_T_BROADCAST
1983 && circuit
->state
== C_STATE_UP
1984 && !if_is_broadcast(circuit
->interface
)) {
1986 EC_LIB_NB_CB_CONFIG_VALIDATE
,
1987 "Cannot configure non-broadcast interface for broadcast operation");
1988 return NB_ERR_VALIDATION
;
1995 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1996 isis_circuit_circ_type_set(circuit
, net_type
);
2004 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2006 int lib_interface_isis_passive_modify(enum nb_event event
,
2007 const struct lyd_node
*dnode
,
2008 union nb_resource
*resource
)
2010 struct isis_circuit
*circuit
;
2011 struct isis_area
*area
;
2012 struct interface
*ifp
;
2013 bool passive
= yang_dnode_get_bool(dnode
, NULL
);
2015 /* validation only applies if we are setting passive to false */
2016 if (!passive
&& event
== NB_EV_VALIDATE
) {
2017 circuit
= nb_running_get_entry(dnode
, NULL
, false);
2020 ifp
= circuit
->interface
;
2023 if (if_is_loopback(ifp
)) {
2024 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
2025 "Loopback is always passive");
2026 return NB_ERR_VALIDATION
;
2030 if (event
!= NB_EV_APPLY
)
2033 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2034 if (circuit
->state
!= C_STATE_UP
) {
2035 circuit
->is_passive
= passive
;
2037 area
= circuit
->area
;
2038 isis_csm_state_change(ISIS_DISABLE
, circuit
, area
);
2039 circuit
->is_passive
= passive
;
2040 isis_csm_state_change(ISIS_ENABLE
, circuit
, area
);
2047 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2049 int lib_interface_isis_password_create(enum nb_event event
,
2050 const struct lyd_node
*dnode
,
2051 union nb_resource
*resource
)
2056 int lib_interface_isis_password_destroy(enum nb_event event
,
2057 const struct lyd_node
*dnode
)
2059 struct isis_circuit
*circuit
;
2061 if (event
!= NB_EV_APPLY
)
2064 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2065 isis_circuit_passwd_unset(circuit
);
2071 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2073 int lib_interface_isis_password_password_modify(enum nb_event event
,
2074 const struct lyd_node
*dnode
,
2075 union nb_resource
*resource
)
2077 struct isis_circuit
*circuit
;
2078 const char *password
;
2080 if (event
!= NB_EV_APPLY
)
2083 password
= yang_dnode_get_string(dnode
, NULL
);
2084 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2086 isis_circuit_passwd_set(circuit
, circuit
->passwd
.type
, password
);
2092 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2094 int lib_interface_isis_password_password_type_modify(
2095 enum nb_event event
, const struct lyd_node
*dnode
,
2096 union nb_resource
*resource
)
2098 struct isis_circuit
*circuit
;
2101 if (event
!= NB_EV_APPLY
)
2104 pass_type
= yang_dnode_get_enum(dnode
, NULL
);
2105 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2106 circuit
->passwd
.type
= pass_type
;
2113 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2115 int lib_interface_isis_disable_three_way_handshake_modify(
2116 enum nb_event event
, const struct lyd_node
*dnode
,
2117 union nb_resource
*resource
)
2119 struct isis_circuit
*circuit
;
2121 if (event
!= NB_EV_APPLY
)
2124 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2125 circuit
->disable_threeway_adj
= yang_dnode_get_bool(dnode
, NULL
);
2132 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2134 static int lib_interface_isis_multi_topology_common(
2135 enum nb_event event
, const struct lyd_node
*dnode
, uint16_t mtid
)
2137 struct isis_circuit
*circuit
;
2141 case NB_EV_VALIDATE
:
2142 circuit
= nb_running_get_entry(dnode
, NULL
, false);
2143 if (circuit
&& circuit
->area
&& circuit
->area
->oldmetric
) {
2145 EC_LIB_NB_CB_CONFIG_VALIDATE
,
2146 "Multi topology IS-IS can only be used with wide metrics");
2147 return NB_ERR_VALIDATION
;
2154 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2155 value
= yang_dnode_get_bool(dnode
, NULL
);
2156 isis_circuit_mt_enabled_set(circuit
, mtid
, value
);
2163 int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2164 enum nb_event event
, const struct lyd_node
*dnode
,
2165 union nb_resource
*resource
)
2167 return lib_interface_isis_multi_topology_common(event
, dnode
,
2168 ISIS_MT_IPV4_UNICAST
);
2173 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2175 int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2176 enum nb_event event
, const struct lyd_node
*dnode
,
2177 union nb_resource
*resource
)
2179 return lib_interface_isis_multi_topology_common(event
, dnode
,
2180 ISIS_MT_IPV4_MULTICAST
);
2185 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2187 int lib_interface_isis_multi_topology_ipv4_management_modify(
2188 enum nb_event event
, const struct lyd_node
*dnode
,
2189 union nb_resource
*resource
)
2191 return lib_interface_isis_multi_topology_common(event
, dnode
,
2197 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2199 int lib_interface_isis_multi_topology_ipv6_unicast_modify(
2200 enum nb_event event
, const struct lyd_node
*dnode
,
2201 union nb_resource
*resource
)
2203 return lib_interface_isis_multi_topology_common(event
, dnode
,
2204 ISIS_MT_IPV6_UNICAST
);
2209 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2211 int lib_interface_isis_multi_topology_ipv6_multicast_modify(
2212 enum nb_event event
, const struct lyd_node
*dnode
,
2213 union nb_resource
*resource
)
2215 return lib_interface_isis_multi_topology_common(event
, dnode
,
2216 ISIS_MT_IPV6_MULTICAST
);
2221 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2223 int lib_interface_isis_multi_topology_ipv6_management_modify(
2224 enum nb_event event
, const struct lyd_node
*dnode
,
2225 union nb_resource
*resource
)
2227 return lib_interface_isis_multi_topology_common(event
, dnode
,
2232 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2234 int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2235 enum nb_event event
, const struct lyd_node
*dnode
,
2236 union nb_resource
*resource
)
2238 return lib_interface_isis_multi_topology_common(event
, dnode
,
2239 ISIS_MT_IPV6_DSTSRC
);