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
;
1553 if (circuit
->state
== C_STATE_UP
|| circuit
->state
== C_STATE_CONF
)
1554 isis_csm_state_change(ISIS_DISABLE
, circuit
, circuit
->area
);
1560 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1562 int lib_interface_isis_area_tag_modify(enum nb_event event
,
1563 const struct lyd_node
*dnode
,
1564 union nb_resource
*resource
)
1566 struct isis_circuit
*circuit
;
1567 struct interface
*ifp
;
1569 const char *area_tag
, *ifname
, *vrfname
;
1571 if (event
== NB_EV_VALIDATE
) {
1572 /* libyang doesn't like relative paths across module boundaries
1574 ifname
= yang_dnode_get_string(dnode
->parent
->parent
, "./name");
1575 vrfname
= yang_dnode_get_string(dnode
->parent
->parent
, "./vrf");
1576 vrf
= vrf_lookup_by_name(vrfname
);
1578 ifp
= if_lookup_by_name(ifname
, vrf
->vrf_id
);
1581 circuit
= circuit_lookup_by_ifp(ifp
, isis
->init_circ_list
);
1582 area_tag
= yang_dnode_get_string(dnode
, NULL
);
1583 if (circuit
&& circuit
->area
&& circuit
->area
->area_tag
1584 && strcmp(circuit
->area
->area_tag
, area_tag
)) {
1585 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1586 "ISIS circuit is already defined on %s",
1587 circuit
->area
->area_tag
);
1588 return NB_ERR_VALIDATION
;
1596 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1598 int lib_interface_isis_circuit_type_modify(enum nb_event event
,
1599 const struct lyd_node
*dnode
,
1600 union nb_resource
*resource
)
1602 int circ_type
= yang_dnode_get_enum(dnode
, NULL
);
1603 struct isis_circuit
*circuit
;
1604 struct interface
*ifp
;
1606 const char *ifname
, *vrfname
;
1609 case NB_EV_VALIDATE
:
1610 /* libyang doesn't like relative paths across module boundaries
1612 ifname
= yang_dnode_get_string(dnode
->parent
->parent
, "./name");
1613 vrfname
= yang_dnode_get_string(dnode
->parent
->parent
, "./vrf");
1614 vrf
= vrf_lookup_by_name(vrfname
);
1616 ifp
= if_lookup_by_name(ifname
, vrf
->vrf_id
);
1619 circuit
= circuit_lookup_by_ifp(ifp
, isis
->init_circ_list
);
1620 if (circuit
&& circuit
->state
== C_STATE_UP
1621 && circuit
->area
->is_type
!= IS_LEVEL_1_AND_2
1622 && circuit
->area
->is_type
!= circ_type
) {
1623 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
1624 "Invalid circuit level for area %s",
1625 circuit
->area
->area_tag
);
1626 return NB_ERR_VALIDATION
;
1633 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1634 isis_circuit_is_type_set(circuit
, circ_type
);
1642 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1644 int lib_interface_isis_ipv4_routing_modify(enum nb_event event
,
1645 const struct lyd_node
*dnode
,
1646 union nb_resource
*resource
)
1649 struct isis_circuit
*circuit
;
1651 if (event
!= NB_EV_APPLY
)
1654 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1655 ipv4
= yang_dnode_get_bool(dnode
, NULL
);
1656 ipv6
= yang_dnode_get_bool(dnode
, "../ipv6-routing");
1657 isis_circuit_af_set(circuit
, ipv4
, ipv6
);
1663 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1665 int lib_interface_isis_ipv6_routing_modify(enum nb_event event
,
1666 const struct lyd_node
*dnode
,
1667 union nb_resource
*resource
)
1670 struct isis_circuit
*circuit
;
1672 if (event
!= NB_EV_APPLY
)
1675 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1676 ipv4
= yang_dnode_exists(dnode
, "../ipv4-routing");
1677 ipv6
= yang_dnode_get_bool(dnode
, NULL
);
1678 isis_circuit_af_set(circuit
, ipv4
, ipv6
);
1684 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
1686 int lib_interface_isis_bfd_monitoring_modify(enum nb_event event
,
1687 const struct lyd_node
*dnode
,
1688 union nb_resource
*resource
)
1690 struct isis_circuit
*circuit
;
1691 bool bfd_monitoring
;
1693 if (event
!= NB_EV_APPLY
)
1696 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1697 bfd_monitoring
= yang_dnode_get_bool(dnode
, NULL
);
1699 if (bfd_monitoring
) {
1700 isis_bfd_circuit_param_set(circuit
, BFD_DEF_MIN_RX
,
1701 BFD_DEF_MIN_TX
, BFD_DEF_DETECT_MULT
,
1704 isis_bfd_circuit_cmd(circuit
, ZEBRA_BFD_DEST_DEREGISTER
);
1705 bfd_info_free(&circuit
->bfd_info
);
1712 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1714 int lib_interface_isis_csnp_interval_level_1_modify(
1715 enum nb_event event
, const struct lyd_node
*dnode
,
1716 union nb_resource
*resource
)
1718 struct isis_circuit
*circuit
;
1720 if (event
!= NB_EV_APPLY
)
1723 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1724 circuit
->csnp_interval
[0] = yang_dnode_get_uint16(dnode
, NULL
);
1730 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1732 int lib_interface_isis_csnp_interval_level_2_modify(
1733 enum nb_event event
, const struct lyd_node
*dnode
,
1734 union nb_resource
*resource
)
1736 struct isis_circuit
*circuit
;
1738 if (event
!= NB_EV_APPLY
)
1741 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1742 circuit
->csnp_interval
[1] = yang_dnode_get_uint16(dnode
, NULL
);
1748 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1750 int lib_interface_isis_psnp_interval_level_1_modify(
1751 enum nb_event event
, const struct lyd_node
*dnode
,
1752 union nb_resource
*resource
)
1754 struct isis_circuit
*circuit
;
1756 if (event
!= NB_EV_APPLY
)
1759 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1760 circuit
->psnp_interval
[0] = yang_dnode_get_uint16(dnode
, NULL
);
1766 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1768 int lib_interface_isis_psnp_interval_level_2_modify(
1769 enum nb_event event
, const struct lyd_node
*dnode
,
1770 union nb_resource
*resource
)
1772 struct isis_circuit
*circuit
;
1774 if (event
!= NB_EV_APPLY
)
1777 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1778 circuit
->psnp_interval
[1] = yang_dnode_get_uint16(dnode
, NULL
);
1784 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
1786 int lib_interface_isis_hello_padding_modify(enum nb_event event
,
1787 const struct lyd_node
*dnode
,
1788 union nb_resource
*resource
)
1790 struct isis_circuit
*circuit
;
1792 if (event
!= NB_EV_APPLY
)
1795 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1796 circuit
->pad_hellos
= yang_dnode_get_bool(dnode
, NULL
);
1802 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
1804 int lib_interface_isis_hello_interval_level_1_modify(
1805 enum nb_event event
, const struct lyd_node
*dnode
,
1806 union nb_resource
*resource
)
1808 struct isis_circuit
*circuit
;
1811 if (event
!= NB_EV_APPLY
)
1814 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1815 interval
= yang_dnode_get_uint32(dnode
, NULL
);
1816 circuit
->hello_interval
[0] = interval
;
1822 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
1824 int lib_interface_isis_hello_interval_level_2_modify(
1825 enum nb_event event
, const struct lyd_node
*dnode
,
1826 union nb_resource
*resource
)
1828 struct isis_circuit
*circuit
;
1831 if (event
!= NB_EV_APPLY
)
1834 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1835 interval
= yang_dnode_get_uint32(dnode
, NULL
);
1836 circuit
->hello_interval
[1] = interval
;
1842 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
1844 int lib_interface_isis_hello_multiplier_level_1_modify(
1845 enum nb_event event
, const struct lyd_node
*dnode
,
1846 union nb_resource
*resource
)
1848 struct isis_circuit
*circuit
;
1851 if (event
!= NB_EV_APPLY
)
1854 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1855 multi
= yang_dnode_get_uint16(dnode
, NULL
);
1856 circuit
->hello_multiplier
[0] = multi
;
1862 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
1864 int lib_interface_isis_hello_multiplier_level_2_modify(
1865 enum nb_event event
, const struct lyd_node
*dnode
,
1866 union nb_resource
*resource
)
1868 struct isis_circuit
*circuit
;
1871 if (event
!= NB_EV_APPLY
)
1874 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1875 multi
= yang_dnode_get_uint16(dnode
, NULL
);
1876 circuit
->hello_multiplier
[1] = multi
;
1882 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
1884 int lib_interface_isis_metric_level_1_modify(enum nb_event event
,
1885 const struct lyd_node
*dnode
,
1886 union nb_resource
*resource
)
1888 struct isis_circuit
*circuit
;
1891 if (event
!= NB_EV_APPLY
)
1894 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1895 met
= yang_dnode_get_uint32(dnode
, NULL
);
1896 isis_circuit_metric_set(circuit
, IS_LEVEL_1
, met
);
1902 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
1904 int lib_interface_isis_metric_level_2_modify(enum nb_event event
,
1905 const struct lyd_node
*dnode
,
1906 union nb_resource
*resource
)
1908 struct isis_circuit
*circuit
;
1911 if (event
!= NB_EV_APPLY
)
1914 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1915 met
= yang_dnode_get_uint32(dnode
, NULL
);
1916 isis_circuit_metric_set(circuit
, IS_LEVEL_2
, met
);
1922 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
1924 int lib_interface_isis_priority_level_1_modify(enum nb_event event
,
1925 const struct lyd_node
*dnode
,
1926 union nb_resource
*resource
)
1928 struct isis_circuit
*circuit
;
1930 if (event
!= NB_EV_APPLY
)
1933 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1934 circuit
->priority
[0] = yang_dnode_get_uint8(dnode
, NULL
);
1940 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
1942 int lib_interface_isis_priority_level_2_modify(enum nb_event event
,
1943 const struct lyd_node
*dnode
,
1944 union nb_resource
*resource
)
1946 struct isis_circuit
*circuit
;
1948 if (event
!= NB_EV_APPLY
)
1951 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1952 circuit
->priority
[1] = yang_dnode_get_uint8(dnode
, NULL
);
1958 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
1960 int lib_interface_isis_network_type_modify(enum nb_event event
,
1961 const struct lyd_node
*dnode
,
1962 union nb_resource
*resource
)
1964 struct isis_circuit
*circuit
;
1965 int net_type
= yang_dnode_get_enum(dnode
, NULL
);
1968 case NB_EV_VALIDATE
:
1969 circuit
= nb_running_get_entry(dnode
, NULL
, false);
1972 if (circuit
->circ_type
== CIRCUIT_T_LOOPBACK
) {
1974 EC_LIB_NB_CB_CONFIG_VALIDATE
,
1975 "Cannot change network type on loopback interface");
1976 return NB_ERR_VALIDATION
;
1978 if (net_type
== CIRCUIT_T_BROADCAST
1979 && circuit
->state
== C_STATE_UP
1980 && !if_is_broadcast(circuit
->interface
)) {
1982 EC_LIB_NB_CB_CONFIG_VALIDATE
,
1983 "Cannot configure non-broadcast interface for broadcast operation");
1984 return NB_ERR_VALIDATION
;
1991 circuit
= nb_running_get_entry(dnode
, NULL
, true);
1992 isis_circuit_circ_type_set(circuit
, net_type
);
2000 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2002 int lib_interface_isis_passive_modify(enum nb_event event
,
2003 const struct lyd_node
*dnode
,
2004 union nb_resource
*resource
)
2006 struct isis_circuit
*circuit
;
2007 struct isis_area
*area
;
2008 struct interface
*ifp
;
2009 bool passive
= yang_dnode_get_bool(dnode
, NULL
);
2011 /* validation only applies if we are setting passive to false */
2012 if (!passive
&& event
== NB_EV_VALIDATE
) {
2013 circuit
= nb_running_get_entry(dnode
, NULL
, false);
2016 ifp
= circuit
->interface
;
2019 if (if_is_loopback(ifp
)) {
2020 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
2021 "Loopback is always passive");
2022 return NB_ERR_VALIDATION
;
2026 if (event
!= NB_EV_APPLY
)
2029 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2030 if (circuit
->state
!= C_STATE_UP
) {
2031 circuit
->is_passive
= passive
;
2033 area
= circuit
->area
;
2034 isis_csm_state_change(ISIS_DISABLE
, circuit
, area
);
2035 circuit
->is_passive
= passive
;
2036 isis_csm_state_change(ISIS_ENABLE
, circuit
, area
);
2043 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2045 int lib_interface_isis_password_create(enum nb_event event
,
2046 const struct lyd_node
*dnode
,
2047 union nb_resource
*resource
)
2052 int lib_interface_isis_password_destroy(enum nb_event event
,
2053 const struct lyd_node
*dnode
)
2055 struct isis_circuit
*circuit
;
2057 if (event
!= NB_EV_APPLY
)
2060 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2061 isis_circuit_passwd_unset(circuit
);
2067 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2069 int lib_interface_isis_password_password_modify(enum nb_event event
,
2070 const struct lyd_node
*dnode
,
2071 union nb_resource
*resource
)
2073 struct isis_circuit
*circuit
;
2074 const char *password
;
2076 if (event
!= NB_EV_APPLY
)
2079 password
= yang_dnode_get_string(dnode
, NULL
);
2080 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2082 isis_circuit_passwd_set(circuit
, circuit
->passwd
.type
, password
);
2088 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2090 int lib_interface_isis_password_password_type_modify(
2091 enum nb_event event
, const struct lyd_node
*dnode
,
2092 union nb_resource
*resource
)
2094 struct isis_circuit
*circuit
;
2097 if (event
!= NB_EV_APPLY
)
2100 pass_type
= yang_dnode_get_enum(dnode
, NULL
);
2101 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2102 circuit
->passwd
.type
= pass_type
;
2109 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2111 int lib_interface_isis_disable_three_way_handshake_modify(
2112 enum nb_event event
, const struct lyd_node
*dnode
,
2113 union nb_resource
*resource
)
2115 struct isis_circuit
*circuit
;
2117 if (event
!= NB_EV_APPLY
)
2120 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2121 circuit
->disable_threeway_adj
= yang_dnode_get_bool(dnode
, NULL
);
2128 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2130 static int lib_interface_isis_multi_topology_common(
2131 enum nb_event event
, const struct lyd_node
*dnode
, uint16_t mtid
)
2133 struct isis_circuit
*circuit
;
2137 case NB_EV_VALIDATE
:
2138 circuit
= nb_running_get_entry(dnode
, NULL
, false);
2139 if (circuit
&& circuit
->area
&& circuit
->area
->oldmetric
) {
2141 EC_LIB_NB_CB_CONFIG_VALIDATE
,
2142 "Multi topology IS-IS can only be used with wide metrics");
2143 return NB_ERR_VALIDATION
;
2150 circuit
= nb_running_get_entry(dnode
, NULL
, true);
2151 value
= yang_dnode_get_bool(dnode
, NULL
);
2152 isis_circuit_mt_enabled_set(circuit
, mtid
, value
);
2159 int lib_interface_isis_multi_topology_ipv4_unicast_modify(
2160 enum nb_event event
, const struct lyd_node
*dnode
,
2161 union nb_resource
*resource
)
2163 return lib_interface_isis_multi_topology_common(event
, dnode
,
2164 ISIS_MT_IPV4_UNICAST
);
2169 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2171 int lib_interface_isis_multi_topology_ipv4_multicast_modify(
2172 enum nb_event event
, const struct lyd_node
*dnode
,
2173 union nb_resource
*resource
)
2175 return lib_interface_isis_multi_topology_common(event
, dnode
,
2176 ISIS_MT_IPV4_MULTICAST
);
2181 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2183 int lib_interface_isis_multi_topology_ipv4_management_modify(
2184 enum nb_event event
, const struct lyd_node
*dnode
,
2185 union nb_resource
*resource
)
2187 return lib_interface_isis_multi_topology_common(event
, dnode
,
2193 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2195 int lib_interface_isis_multi_topology_ipv6_unicast_modify(
2196 enum nb_event event
, const struct lyd_node
*dnode
,
2197 union nb_resource
*resource
)
2199 return lib_interface_isis_multi_topology_common(event
, dnode
,
2200 ISIS_MT_IPV6_UNICAST
);
2205 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2207 int lib_interface_isis_multi_topology_ipv6_multicast_modify(
2208 enum nb_event event
, const struct lyd_node
*dnode
,
2209 union nb_resource
*resource
)
2211 return lib_interface_isis_multi_topology_common(event
, dnode
,
2212 ISIS_MT_IPV6_MULTICAST
);
2217 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2219 int lib_interface_isis_multi_topology_ipv6_management_modify(
2220 enum nb_event event
, const struct lyd_node
*dnode
,
2221 union nb_resource
*resource
)
2223 return lib_interface_isis_multi_topology_common(event
, dnode
,
2228 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2230 int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
2231 enum nb_event event
, const struct lyd_node
*dnode
,
2232 union nb_resource
*resource
)
2234 return lib_interface_isis_multi_topology_common(event
, dnode
,
2235 ISIS_MT_IPV6_DSTSRC
);