]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_nb_config.c
Merge pull request #6390 from opensourcerouting/bfd-cp-fix
[mirror_frr.git] / isisd / isis_nb_config.c
CommitLineData
2a1c520e
RW
1/*
2 * Copyright (C) 2001,2002 Sampo Saaristo
3 * Tampere University of Technology
4 * Institute of Communications Engineering
5 * Copyright (C) 2018 Volta Networks
6 * Emanuele Di Pascale
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <zebra.h>
24
25#include "northbound.h"
26#include "linklist.h"
27#include "log.h"
28#include "bfd.h"
29#include "spf_backoff.h"
30#include "lib_errors.h"
31#include "vrf.h"
32
33#include "isisd/isisd.h"
34#include "isisd/isis_nb.h"
35#include "isisd/isis_common.h"
36#include "isisd/isis_bfd.h"
37#include "isisd/isis_circuit.h"
38#include "isisd/isis_lsp.h"
39#include "isisd/isis_dynhn.h"
40#include "isisd/isis_misc.h"
41#include "isisd/isis_csm.h"
42#include "isisd/isis_adjacency.h"
43#include "isisd/isis_spf.h"
44#include "isisd/isis_te.h"
45#include "isisd/isis_memory.h"
46#include "isisd/isis_mt.h"
47#include "isisd/isis_redist.h"
48
49/*
50 * XPath: /frr-isisd:isis/instance
51 */
60ee8be1 52int isis_instance_create(struct nb_cb_create_args *args)
2a1c520e
RW
53{
54 struct isis_area *area;
55 const char *area_tag;
56
60ee8be1 57 if (args->event != NB_EV_APPLY)
2a1c520e
RW
58 return NB_OK;
59
60ee8be1 60 area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
2a1c520e
RW
61 area = isis_area_lookup(area_tag);
62 if (area)
63 return NB_ERR_INCONSISTENCY;
64
65 area = isis_area_create(area_tag);
66 /* save area in dnode to avoid looking it up all the time */
60ee8be1 67 nb_running_set_entry(args->dnode, area);
2a1c520e
RW
68
69 return NB_OK;
70}
71
60ee8be1 72int isis_instance_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
73{
74 struct isis_area *area;
75
60ee8be1 76 if (args->event != NB_EV_APPLY)
2a1c520e
RW
77 return NB_OK;
78
60ee8be1 79 area = nb_running_unset_entry(args->dnode);
2a1c520e
RW
80 isis_area_destroy(area->area_tag);
81
82 return NB_OK;
83}
84
85/*
86 * XPath: /frr-isisd:isis/instance/is-type
87 */
60ee8be1 88int isis_instance_is_type_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
89{
90 struct isis_area *area;
91 int type;
92
60ee8be1 93 if (args->event != NB_EV_APPLY)
2a1c520e
RW
94 return NB_OK;
95
60ee8be1
RW
96 area = nb_running_get_entry(args->dnode, NULL, true);
97 type = yang_dnode_get_enum(args->dnode, NULL);
2a1c520e
RW
98 isis_area_is_type_set(area, type);
99
100 return NB_OK;
101}
102
103/*
104 * XPath: /frr-isisd:isis/instance/area-address
105 */
60ee8be1 106int isis_instance_area_address_create(struct nb_cb_create_args *args)
2a1c520e
RW
107{
108 struct isis_area *area;
109 struct area_addr addr, *addrr = NULL, *addrp = NULL;
110 struct listnode *node;
111 uint8_t buff[255];
60ee8be1 112 const char *net_title = yang_dnode_get_string(args->dnode, NULL);
2a1c520e 113
60ee8be1 114 switch (args->event) {
2a1c520e
RW
115 case NB_EV_VALIDATE:
116 addr.addr_len = dotformat2buff(buff, net_title);
117 memcpy(addr.area_addr, buff, addr.addr_len);
118 if (addr.area_addr[addr.addr_len - 1] != 0) {
10bdc68f
RW
119 snprintf(
120 args->errmsg, args->errmsg_len,
2a1c520e
RW
121 "nsel byte (last byte) in area address must be 0");
122 return NB_ERR_VALIDATION;
123 }
124 if (isis->sysid_set) {
125 /* Check that the SystemID portions match */
126 if (memcmp(isis->sysid, GETSYSID((&addr)),
127 ISIS_SYS_ID_LEN)) {
10bdc68f
RW
128 snprintf(
129 args->errmsg, args->errmsg_len,
2a1c520e
RW
130 "System ID must not change when defining additional area addresses");
131 return NB_ERR_VALIDATION;
132 }
133 }
134 break;
135 case NB_EV_PREPARE:
136 addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
137 addrr->addr_len = dotformat2buff(buff, net_title);
138 memcpy(addrr->area_addr, buff, addrr->addr_len);
60ee8be1 139 args->resource->ptr = addrr;
2a1c520e
RW
140 break;
141 case NB_EV_ABORT:
60ee8be1 142 XFREE(MTYPE_ISIS_AREA_ADDR, args->resource->ptr);
2a1c520e
RW
143 break;
144 case NB_EV_APPLY:
60ee8be1
RW
145 area = nb_running_get_entry(args->dnode, NULL, true);
146 addrr = args->resource->ptr;
2a1c520e
RW
147
148 if (isis->sysid_set == 0) {
149 /*
150 * First area address - get the SystemID for this router
151 */
152 memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
153 isis->sysid_set = 1;
154 } else {
155 /* check that we don't already have this address */
156 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
157 addrp)) {
158 if ((addrp->addr_len + ISIS_SYS_ID_LEN
159 + ISIS_NSEL_LEN)
160 != (addrr->addr_len))
161 continue;
162 if (!memcmp(addrp->area_addr, addrr->area_addr,
163 addrr->addr_len)) {
164 XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
165 return NB_OK; /* silent fail */
166 }
167 }
168 }
169
170 /*Forget the systemID part of the address */
171 addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
172 assert(area->area_addrs); /* to silence scan-build sillyness */
173 listnode_add(area->area_addrs, addrr);
174
175 /* only now we can safely generate our LSPs for this area */
176 if (listcount(area->area_addrs) > 0) {
177 if (area->is_type & IS_LEVEL_1)
178 lsp_generate(area, IS_LEVEL_1);
179 if (area->is_type & IS_LEVEL_2)
180 lsp_generate(area, IS_LEVEL_2);
181 }
182 break;
183 }
184
185 return NB_OK;
186}
187
60ee8be1 188int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
189{
190 struct area_addr addr, *addrp = NULL;
191 struct listnode *node;
192 uint8_t buff[255];
193 struct isis_area *area;
194 const char *net_title;
195
60ee8be1 196 if (args->event != NB_EV_APPLY)
2a1c520e
RW
197 return NB_OK;
198
60ee8be1 199 net_title = yang_dnode_get_string(args->dnode, NULL);
2a1c520e
RW
200 addr.addr_len = dotformat2buff(buff, net_title);
201 memcpy(addr.area_addr, buff, (int)addr.addr_len);
60ee8be1 202 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
203 for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
204 if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
205 && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
206 break;
207 }
208 if (!addrp)
209 return NB_ERR_INCONSISTENCY;
210
211 listnode_delete(area->area_addrs, addrp);
212 XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
213 /*
214 * Last area address - reset the SystemID for this router
215 */
216 if (listcount(area->area_addrs) == 0) {
217 memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
218 isis->sysid_set = 0;
219 if (isis->debugs & DEBUG_EVENTS)
220 zlog_debug("Router has no SystemID");
221 }
222
223 return NB_OK;
224}
225
226/*
227 * XPath: /frr-isisd:isis/instance/dynamic-hostname
228 */
60ee8be1 229int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
230{
231 struct isis_area *area;
232
60ee8be1 233 if (args->event != NB_EV_APPLY)
2a1c520e
RW
234 return NB_OK;
235
60ee8be1
RW
236 area = nb_running_get_entry(args->dnode, NULL, true);
237 isis_area_dynhostname_set(area, yang_dnode_get_bool(args->dnode, NULL));
2a1c520e
RW
238
239 return NB_OK;
240}
241
242/*
243 * XPath: /frr-isisd:isis/instance/attached
244 */
60ee8be1 245int isis_instance_attached_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
246{
247 struct isis_area *area;
248 bool attached;
249
60ee8be1 250 if (args->event != NB_EV_APPLY)
2a1c520e
RW
251 return NB_OK;
252
60ee8be1
RW
253 area = nb_running_get_entry(args->dnode, NULL, true);
254 attached = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
255 isis_area_attached_bit_set(area, attached);
256
257 return NB_OK;
258}
259
260/*
261 * XPath: /frr-isisd:isis/instance/overload
262 */
60ee8be1 263int isis_instance_overload_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
264{
265 struct isis_area *area;
266 bool overload;
267
60ee8be1 268 if (args->event != NB_EV_APPLY)
2a1c520e
RW
269 return NB_OK;
270
60ee8be1
RW
271 area = nb_running_get_entry(args->dnode, NULL, true);
272 overload = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
273 isis_area_overload_bit_set(area, overload);
274
275 return NB_OK;
276}
277
278/*
279 * XPath: /frr-isisd:isis/instance/metric-style
280 */
60ee8be1 281int isis_instance_metric_style_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
282{
283 struct isis_area *area;
284 bool old_metric, new_metric;
60ee8be1
RW
285 enum isis_metric_style metric_style =
286 yang_dnode_get_enum(args->dnode, NULL);
2a1c520e 287
60ee8be1 288 if (args->event != NB_EV_APPLY)
2a1c520e
RW
289 return NB_OK;
290
60ee8be1 291 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
292 old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true;
293 new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true;
294 isis_area_metricstyle_set(area, old_metric, new_metric);
295
296 return NB_OK;
297}
298
299/*
300 * XPath: /frr-isisd:isis/instance/purge-originator
301 */
60ee8be1 302int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
303{
304 struct isis_area *area;
305
60ee8be1 306 if (args->event != NB_EV_APPLY)
2a1c520e
RW
307 return NB_OK;
308
60ee8be1
RW
309 area = nb_running_get_entry(args->dnode, NULL, true);
310 area->purge_originator = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
311
312 return NB_OK;
313}
314
315/*
316 * XPath: /frr-isisd:isis/instance/lsp/mtu
317 */
60ee8be1 318int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
319{
320 struct listnode *node;
321 struct isis_circuit *circuit;
60ee8be1 322 uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
323 struct isis_area *area;
324
60ee8be1 325 switch (args->event) {
2a1c520e 326 case NB_EV_VALIDATE:
60ee8be1 327 area = nb_running_get_entry(args->dnode, NULL, false);
2a1c520e
RW
328 if (!area)
329 break;
330 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
331 if (circuit->state != C_STATE_INIT
332 && circuit->state != C_STATE_UP)
333 continue;
334 if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
10bdc68f
RW
335 snprintf(
336 args->errmsg, args->errmsg_len,
2a1c520e
RW
337 "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
338 circuit->interface->name,
339 isis_circuit_pdu_size(circuit));
340 return NB_ERR_VALIDATION;
341 }
342 }
343 break;
344 case NB_EV_PREPARE:
345 case NB_EV_ABORT:
346 break;
347 case NB_EV_APPLY:
60ee8be1 348 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
349 isis_area_lsp_mtu_set(area, lsp_mtu);
350 break;
351 }
352
353 return NB_OK;
354}
355
356/*
d2c970ff 357 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval
2a1c520e
RW
358 */
359int isis_instance_lsp_refresh_interval_level_1_modify(
60ee8be1 360 struct nb_cb_modify_args *args)
2a1c520e
RW
361{
362 struct isis_area *area;
363 uint16_t refr_int;
364
60ee8be1 365 if (args->event != NB_EV_APPLY)
2a1c520e
RW
366 return NB_OK;
367
60ee8be1
RW
368 refr_int = yang_dnode_get_uint16(args->dnode, NULL);
369 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
370 isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int);
371
372 return NB_OK;
373}
374
375/*
d2c970ff 376 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval
2a1c520e
RW
377 */
378int isis_instance_lsp_refresh_interval_level_2_modify(
60ee8be1 379 struct nb_cb_modify_args *args)
2a1c520e
RW
380{
381 struct isis_area *area;
382 uint16_t refr_int;
383
60ee8be1 384 if (args->event != NB_EV_APPLY)
2a1c520e
RW
385 return NB_OK;
386
60ee8be1
RW
387 refr_int = yang_dnode_get_uint16(args->dnode, NULL);
388 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
389 isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int);
390
391 return NB_OK;
392}
393
394/*
d2c970ff 395 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime
2a1c520e
RW
396 */
397int isis_instance_lsp_maximum_lifetime_level_1_modify(
60ee8be1 398 struct nb_cb_modify_args *args)
2a1c520e
RW
399{
400 struct isis_area *area;
401 uint16_t max_lt;
402
60ee8be1 403 if (args->event != NB_EV_APPLY)
2a1c520e
RW
404 return NB_OK;
405
60ee8be1
RW
406 max_lt = yang_dnode_get_uint16(args->dnode, NULL);
407 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
408 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt);
409
410 return NB_OK;
411}
412
413/*
d2c970ff 414 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime
2a1c520e
RW
415 */
416int isis_instance_lsp_maximum_lifetime_level_2_modify(
60ee8be1 417 struct nb_cb_modify_args *args)
2a1c520e
RW
418{
419 struct isis_area *area;
420 uint16_t max_lt;
421
60ee8be1 422 if (args->event != NB_EV_APPLY)
2a1c520e
RW
423 return NB_OK;
424
60ee8be1
RW
425 max_lt = yang_dnode_get_uint16(args->dnode, NULL);
426 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
427 isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt);
428
429 return NB_OK;
430}
431
432/*
d2c970ff 433 * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/generation-interval
2a1c520e
RW
434 */
435int isis_instance_lsp_generation_interval_level_1_modify(
60ee8be1 436 struct nb_cb_modify_args *args)
2a1c520e
RW
437{
438 struct isis_area *area;
439 uint16_t gen_int;
440
60ee8be1 441 if (args->event != NB_EV_APPLY)
2a1c520e
RW
442 return NB_OK;
443
60ee8be1
RW
444 gen_int = yang_dnode_get_uint16(args->dnode, NULL);
445 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
446 area->lsp_gen_interval[0] = gen_int;
447
448 return NB_OK;
449}
450
451/*
d2c970ff 452 * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/generation-interval
2a1c520e
RW
453 */
454int isis_instance_lsp_generation_interval_level_2_modify(
60ee8be1 455 struct nb_cb_modify_args *args)
2a1c520e
RW
456{
457 struct isis_area *area;
458 uint16_t gen_int;
459
60ee8be1 460 if (args->event != NB_EV_APPLY)
2a1c520e
RW
461 return NB_OK;
462
60ee8be1
RW
463 gen_int = yang_dnode_get_uint16(args->dnode, NULL);
464 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
465 area->lsp_gen_interval[1] = gen_int;
466
467 return NB_OK;
468}
469
470/*
471 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
472 */
60ee8be1 473void ietf_backoff_delay_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 474{
60ee8be1
RW
475 long init_delay = yang_dnode_get_uint16(args->dnode, "./init-delay");
476 long short_delay = yang_dnode_get_uint16(args->dnode, "./short-delay");
477 long long_delay = yang_dnode_get_uint16(args->dnode, "./long-delay");
478 long holddown = yang_dnode_get_uint16(args->dnode, "./hold-down");
479 long timetolearn =
480 yang_dnode_get_uint16(args->dnode, "./time-to-learn");
481 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
482 size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx");
483 char *buf = XCALLOC(MTYPE_TMP, bufsiz);
484
485 snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
486 spf_backoff_free(area->spf_delay_ietf[0]);
487 area->spf_delay_ietf[0] =
488 spf_backoff_new(master, buf, init_delay, short_delay,
489 long_delay, holddown, timetolearn);
490
491 snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
492 spf_backoff_free(area->spf_delay_ietf[1]);
493 area->spf_delay_ietf[1] =
494 spf_backoff_new(master, buf, init_delay, short_delay,
495 long_delay, holddown, timetolearn);
496
497 XFREE(MTYPE_TMP, buf);
498}
499
60ee8be1 500int isis_instance_spf_ietf_backoff_delay_create(struct nb_cb_create_args *args)
2a1c520e
RW
501{
502 /* All the work is done in the apply_finish */
503 return NB_OK;
504}
505
60ee8be1
RW
506int isis_instance_spf_ietf_backoff_delay_destroy(
507 struct nb_cb_destroy_args *args)
2a1c520e
RW
508{
509 struct isis_area *area;
510
60ee8be1 511 if (args->event != NB_EV_APPLY)
2a1c520e
RW
512 return NB_OK;
513
60ee8be1 514 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
515 spf_backoff_free(area->spf_delay_ietf[0]);
516 spf_backoff_free(area->spf_delay_ietf[1]);
517 area->spf_delay_ietf[0] = NULL;
518 area->spf_delay_ietf[1] = NULL;
519
520 return NB_OK;
521}
522
523/*
524 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
525 */
526int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
60ee8be1 527 struct nb_cb_modify_args *args)
2a1c520e
RW
528{
529 /* All the work is done in the apply_finish */
530 return NB_OK;
531}
532
533/*
534 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
535 */
536int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
60ee8be1 537 struct nb_cb_modify_args *args)
2a1c520e
RW
538{
539 /* All the work is done in the apply_finish */
540 return NB_OK;
541}
542
543/*
544 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
545 */
546int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
60ee8be1 547 struct nb_cb_modify_args *args)
2a1c520e
RW
548{
549 /* All the work is done in the apply_finish */
550 return NB_OK;
551}
552
553/*
554 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
555 */
556int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
60ee8be1 557 struct nb_cb_modify_args *args)
2a1c520e
RW
558{
559 /* All the work is done in the apply_finish */
560 return NB_OK;
561}
562
563/*
564 * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
565 */
566int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
60ee8be1 567 struct nb_cb_modify_args *args)
2a1c520e
RW
568{
569 /* All the work is done in the apply_finish */
570 return NB_OK;
571}
572
573/*
574 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
575 */
576int isis_instance_spf_minimum_interval_level_1_modify(
60ee8be1 577 struct nb_cb_modify_args *args)
2a1c520e
RW
578{
579 struct isis_area *area;
580
60ee8be1 581 if (args->event != NB_EV_APPLY)
2a1c520e
RW
582 return NB_OK;
583
60ee8be1
RW
584 area = nb_running_get_entry(args->dnode, NULL, true);
585 area->min_spf_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
586
587 return NB_OK;
588}
589
590/*
591 * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
592 */
593int isis_instance_spf_minimum_interval_level_2_modify(
60ee8be1 594 struct nb_cb_modify_args *args)
2a1c520e
RW
595{
596 struct isis_area *area;
597
60ee8be1 598 if (args->event != NB_EV_APPLY)
2a1c520e
RW
599 return NB_OK;
600
60ee8be1
RW
601 area = nb_running_get_entry(args->dnode, NULL, true);
602 area->min_spf_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
603
604 return NB_OK;
605}
606
607/*
608 * XPath: /frr-isisd:isis/instance/area-password
609 */
60ee8be1 610void area_password_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 611{
60ee8be1
RW
612 const char *password = yang_dnode_get_string(args->dnode, "./password");
613 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
614 int pass_type = yang_dnode_get_enum(args->dnode, "./password-type");
615 uint8_t snp_auth =
616 yang_dnode_get_enum(args->dnode, "./authenticate-snp");
2a1c520e
RW
617
618 switch (pass_type) {
619 case ISIS_PASSWD_TYPE_CLEARTXT:
620 isis_area_passwd_cleartext_set(area, IS_LEVEL_1, password,
621 snp_auth);
622 break;
623 case ISIS_PASSWD_TYPE_HMAC_MD5:
624 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_1, password,
625 snp_auth);
626 break;
627 }
628}
629
60ee8be1 630int isis_instance_area_password_create(struct nb_cb_create_args *args)
2a1c520e
RW
631{
632 /* actual setting is done in apply_finish */
633 return NB_OK;
634}
635
60ee8be1 636int isis_instance_area_password_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
637{
638 struct isis_area *area;
639
60ee8be1 640 if (args->event != NB_EV_APPLY)
2a1c520e
RW
641 return NB_OK;
642
60ee8be1 643 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
644 isis_area_passwd_unset(area, IS_LEVEL_1);
645
646 return NB_OK;
647}
648
649/*
650 * XPath: /frr-isisd:isis/instance/area-password/password
651 */
60ee8be1 652int isis_instance_area_password_password_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
653{
654 /* actual setting is done in apply_finish */
655 return NB_OK;
656}
657
658/*
659 * XPath: /frr-isisd:isis/instance/area-password/password-type
660 */
661int isis_instance_area_password_password_type_modify(
60ee8be1 662 struct nb_cb_modify_args *args)
2a1c520e
RW
663{
664 /* actual setting is done in apply_finish */
665 return NB_OK;
666}
667
668/*
669 * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
670 */
671int isis_instance_area_password_authenticate_snp_modify(
60ee8be1 672 struct nb_cb_modify_args *args)
2a1c520e
RW
673{
674 /* actual setting is done in apply_finish */
675 return NB_OK;
676}
677
678/*
679 * XPath: /frr-isisd:isis/instance/domain-password
680 */
60ee8be1 681void domain_password_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 682{
60ee8be1
RW
683 const char *password = yang_dnode_get_string(args->dnode, "./password");
684 struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true);
685 int pass_type = yang_dnode_get_enum(args->dnode, "./password-type");
686 uint8_t snp_auth =
687 yang_dnode_get_enum(args->dnode, "./authenticate-snp");
2a1c520e
RW
688
689 switch (pass_type) {
690 case ISIS_PASSWD_TYPE_CLEARTXT:
691 isis_area_passwd_cleartext_set(area, IS_LEVEL_2, password,
692 snp_auth);
693 break;
694 case ISIS_PASSWD_TYPE_HMAC_MD5:
695 isis_area_passwd_hmac_md5_set(area, IS_LEVEL_2, password,
696 snp_auth);
697 break;
698 }
699}
700
60ee8be1 701int isis_instance_domain_password_create(struct nb_cb_create_args *args)
2a1c520e
RW
702{
703 /* actual setting is done in apply_finish */
704 return NB_OK;
705}
706
60ee8be1 707int isis_instance_domain_password_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
708{
709 struct isis_area *area;
710
60ee8be1 711 if (args->event != NB_EV_APPLY)
2a1c520e
RW
712 return NB_OK;
713
60ee8be1 714 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
715 isis_area_passwd_unset(area, IS_LEVEL_2);
716
717 return NB_OK;
718}
719
720/*
721 * XPath: /frr-isisd:isis/instance/domain-password/password
722 */
60ee8be1
RW
723int isis_instance_domain_password_password_modify(
724 struct nb_cb_modify_args *args)
2a1c520e
RW
725{
726 /* actual setting is done in apply_finish */
727 return NB_OK;
728}
729
730/*
731 * XPath: /frr-isisd:isis/instance/domain-password/password-type
732 */
733int isis_instance_domain_password_password_type_modify(
60ee8be1 734 struct nb_cb_modify_args *args)
2a1c520e
RW
735{
736 /* actual setting is done in apply_finish */
737 return NB_OK;
738}
739
740/*
741 * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
742 */
743int isis_instance_domain_password_authenticate_snp_modify(
60ee8be1 744 struct nb_cb_modify_args *args)
2a1c520e
RW
745{
746 /* actual setting is done in apply_finish */
747 return NB_OK;
748}
749
750/*
751 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
752 */
753void default_info_origin_apply_finish(const struct lyd_node *dnode, int family)
754{
755 int originate_type = DEFAULT_ORIGINATE;
756 unsigned long metric = 0;
757 const char *routemap = NULL;
758 struct isis_area *area = nb_running_get_entry(dnode, NULL, true);
759 int level = yang_dnode_get_enum(dnode, "./level");
760
761 if (yang_dnode_get_bool(dnode, "./always")) {
762 originate_type = DEFAULT_ORIGINATE_ALWAYS;
763 } else if (family == AF_INET6) {
764 zlog_warn(
765 "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
766 __func__);
767 }
768
769 if (yang_dnode_exists(dnode, "./metric"))
770 metric = yang_dnode_get_uint32(dnode, "./metric");
771 if (yang_dnode_exists(dnode, "./route-map"))
772 routemap = yang_dnode_get_string(dnode, "./route-map");
773
774 isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
775 originate_type);
776}
777
60ee8be1 778void default_info_origin_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 779{
60ee8be1 780 default_info_origin_apply_finish(args->dnode, AF_INET);
2a1c520e
RW
781}
782
60ee8be1 783void default_info_origin_ipv6_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 784{
60ee8be1 785 default_info_origin_apply_finish(args->dnode, AF_INET6);
2a1c520e
RW
786}
787
788int isis_instance_default_information_originate_ipv4_create(
60ee8be1 789 struct nb_cb_create_args *args)
2a1c520e
RW
790{
791 /* It's all done by default_info_origin_apply_finish */
792 return NB_OK;
793}
794
795int isis_instance_default_information_originate_ipv4_destroy(
60ee8be1 796 struct nb_cb_destroy_args *args)
2a1c520e
RW
797{
798 struct isis_area *area;
799 int level;
800
60ee8be1 801 if (args->event != NB_EV_APPLY)
2a1c520e
RW
802 return NB_OK;
803
60ee8be1
RW
804 area = nb_running_get_entry(args->dnode, NULL, true);
805 level = yang_dnode_get_enum(args->dnode, "./level");
2a1c520e
RW
806 isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
807
808 return NB_OK;
809}
810
811/*
812 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
813 */
814int isis_instance_default_information_originate_ipv4_always_modify(
60ee8be1 815 struct nb_cb_modify_args *args)
2a1c520e
RW
816{
817 /* It's all done by default_info_origin_apply_finish */
818 return NB_OK;
819}
820
821/*
822 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
823 */
824int isis_instance_default_information_originate_ipv4_route_map_modify(
60ee8be1 825 struct nb_cb_modify_args *args)
2a1c520e
RW
826{
827 /* It's all done by default_info_origin_apply_finish */
828 return NB_OK;
829}
830
831int isis_instance_default_information_originate_ipv4_route_map_destroy(
60ee8be1 832 struct nb_cb_destroy_args *args)
2a1c520e
RW
833{
834 /* It's all done by default_info_origin_apply_finish */
835 return NB_OK;
836}
837
838/*
839 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
840 */
841int isis_instance_default_information_originate_ipv4_metric_modify(
60ee8be1 842 struct nb_cb_modify_args *args)
2a1c520e
RW
843{
844 /* It's all done by default_info_origin_apply_finish */
845 return NB_OK;
846}
847
848/*
849 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
850 */
851int isis_instance_default_information_originate_ipv6_create(
60ee8be1 852 struct nb_cb_create_args *args)
2a1c520e
RW
853{
854 /* It's all done by default_info_origin_apply_finish */
855 return NB_OK;
856}
857
858int isis_instance_default_information_originate_ipv6_destroy(
60ee8be1 859 struct nb_cb_destroy_args *args)
2a1c520e
RW
860{
861 struct isis_area *area;
862 int level;
863
60ee8be1 864 if (args->event != NB_EV_APPLY)
2a1c520e
RW
865 return NB_OK;
866
60ee8be1
RW
867 area = nb_running_get_entry(args->dnode, NULL, true);
868 level = yang_dnode_get_enum(args->dnode, "./level");
2a1c520e
RW
869 isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
870
871 return NB_OK;
872}
873
874/*
875 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
876 */
877int isis_instance_default_information_originate_ipv6_always_modify(
60ee8be1 878 struct nb_cb_modify_args *args)
2a1c520e
RW
879{
880 /* It's all done by default_info_origin_apply_finish */
881 return NB_OK;
882}
883
884/*
885 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
886 */
887int isis_instance_default_information_originate_ipv6_route_map_modify(
60ee8be1 888 struct nb_cb_modify_args *args)
2a1c520e
RW
889{
890 /* It's all done by default_info_origin_apply_finish */
891 return NB_OK;
892}
893
894int isis_instance_default_information_originate_ipv6_route_map_destroy(
60ee8be1 895 struct nb_cb_destroy_args *args)
2a1c520e
RW
896{
897 /* It's all done by default_info_origin_apply_finish */
898 return NB_OK;
899}
900
901/*
902 * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
903 */
904int isis_instance_default_information_originate_ipv6_metric_modify(
60ee8be1 905 struct nb_cb_modify_args *args)
2a1c520e
RW
906{
907 /* It's all done by default_info_origin_apply_finish */
908 return NB_OK;
909}
910
911/*
912 * XPath: /frr-isisd:isis/instance/redistribute/ipv4
913 */
914void redistribute_apply_finish(const struct lyd_node *dnode, int family)
915{
916 assert(family == AF_INET || family == AF_INET6);
917 int type, level;
918 unsigned long metric = 0;
919 const char *routemap = NULL;
920 struct isis_area *area;
921
922 type = yang_dnode_get_enum(dnode, "./protocol");
923 level = yang_dnode_get_enum(dnode, "./level");
924 area = nb_running_get_entry(dnode, NULL, true);
925
926 if (yang_dnode_exists(dnode, "./metric"))
927 metric = yang_dnode_get_uint32(dnode, "./metric");
928 if (yang_dnode_exists(dnode, "./route-map"))
929 routemap = yang_dnode_get_string(dnode, "./route-map");
930
931 isis_redist_set(area, level, family, type, metric, routemap, 0);
932}
933
60ee8be1 934void redistribute_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 935{
60ee8be1 936 redistribute_apply_finish(args->dnode, AF_INET);
2a1c520e
RW
937}
938
60ee8be1 939void redistribute_ipv6_apply_finish(struct nb_cb_apply_finish_args *args)
2a1c520e 940{
60ee8be1 941 redistribute_apply_finish(args->dnode, AF_INET6);
2a1c520e
RW
942}
943
60ee8be1 944int isis_instance_redistribute_ipv4_create(struct nb_cb_create_args *args)
2a1c520e
RW
945{
946 /* It's all done by redistribute_apply_finish */
947 return NB_OK;
948}
949
60ee8be1 950int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
951{
952 struct isis_area *area;
953 int level, type;
954
60ee8be1 955 if (args->event != NB_EV_APPLY)
2a1c520e
RW
956 return NB_OK;
957
60ee8be1
RW
958 area = nb_running_get_entry(args->dnode, NULL, true);
959 level = yang_dnode_get_enum(args->dnode, "./level");
960 type = yang_dnode_get_enum(args->dnode, "./protocol");
2a1c520e
RW
961 isis_redist_unset(area, level, AF_INET, type);
962
963 return NB_OK;
964}
965
966/*
967 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
968 */
969int isis_instance_redistribute_ipv4_route_map_modify(
60ee8be1 970 struct nb_cb_modify_args *args)
2a1c520e
RW
971{
972 /* It's all done by redistribute_apply_finish */
973 return NB_OK;
974}
975
976int isis_instance_redistribute_ipv4_route_map_destroy(
60ee8be1 977 struct nb_cb_destroy_args *args)
2a1c520e
RW
978{
979 /* It's all done by redistribute_apply_finish */
980 return NB_OK;
981}
982
983/*
984 * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
985 */
60ee8be1
RW
986int isis_instance_redistribute_ipv4_metric_modify(
987 struct nb_cb_modify_args *args)
2a1c520e
RW
988{
989 /* It's all done by redistribute_apply_finish */
990 return NB_OK;
991}
992
993/*
994 * XPath: /frr-isisd:isis/instance/redistribute/ipv6
995 */
60ee8be1 996int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args)
2a1c520e
RW
997{
998 /* It's all done by redistribute_apply_finish */
999 return NB_OK;
1000}
1001
60ee8be1 1002int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
1003{
1004 struct isis_area *area;
1005 int level, type;
1006
60ee8be1 1007 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1008 return NB_OK;
1009
60ee8be1
RW
1010 area = nb_running_get_entry(args->dnode, NULL, true);
1011 level = yang_dnode_get_enum(args->dnode, "./level");
1012 type = yang_dnode_get_enum(args->dnode, "./protocol");
2a1c520e
RW
1013 isis_redist_unset(area, level, AF_INET6, type);
1014
1015 return NB_OK;
1016}
1017
1018/*
1019 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
1020 */
1021int isis_instance_redistribute_ipv6_route_map_modify(
60ee8be1 1022 struct nb_cb_modify_args *args)
2a1c520e
RW
1023{
1024 /* It's all done by redistribute_apply_finish */
1025 return NB_OK;
1026}
1027
1028int isis_instance_redistribute_ipv6_route_map_destroy(
60ee8be1 1029 struct nb_cb_destroy_args *args)
2a1c520e
RW
1030{
1031 /* It's all done by redistribute_apply_finish */
1032 return NB_OK;
1033}
1034
1035/*
1036 * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
1037 */
60ee8be1
RW
1038int isis_instance_redistribute_ipv6_metric_modify(
1039 struct nb_cb_modify_args *args)
2a1c520e
RW
1040{
1041 /* It's all done by redistribute_apply_finish */
1042 return NB_OK;
1043}
1044
1045/*
1046 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
1047 */
1048static int isis_multi_topology_common(enum nb_event event,
1049 const struct lyd_node *dnode,
10bdc68f 1050 char *errmsg, size_t errmsg_len,
2a1c520e
RW
1051 const char *topology, bool create)
1052{
1053 struct isis_area *area;
1054 struct isis_area_mt_setting *setting;
1055 uint16_t mtid = isis_str2mtid(topology);
1056
1057 switch (event) {
1058 case NB_EV_VALIDATE:
1059 if (mtid == (uint16_t)-1) {
10bdc68f
RW
1060 snprintf(errmsg, errmsg_len, "Unknown topology %s",
1061 topology);
2a1c520e
RW
1062 return NB_ERR_VALIDATION;
1063 }
1064 break;
1065 case NB_EV_PREPARE:
1066 case NB_EV_ABORT:
1067 break;
1068 case NB_EV_APPLY:
1069 area = nb_running_get_entry(dnode, NULL, true);
1070 setting = area_get_mt_setting(area, mtid);
1071 setting->enabled = create;
1072 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1073 break;
1074 }
1075
1076 return NB_OK;
1077}
1078
1079static int isis_multi_topology_overload_common(enum nb_event event,
1080 const struct lyd_node *dnode,
1081 const char *topology)
1082{
1083 struct isis_area *area;
1084 struct isis_area_mt_setting *setting;
1085 uint16_t mtid = isis_str2mtid(topology);
1086
1087 /* validation is done in isis_multi_topology_common */
1088 if (event != NB_EV_APPLY)
1089 return NB_OK;
1090
1091 area = nb_running_get_entry(dnode, NULL, true);
1092 setting = area_get_mt_setting(area, mtid);
1093 setting->overload = yang_dnode_get_bool(dnode, NULL);
1094 if (setting->enabled)
1095 lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
1096
1097 return NB_OK;
1098}
1099
1100int isis_instance_multi_topology_ipv4_multicast_create(
60ee8be1 1101 struct nb_cb_create_args *args)
2a1c520e 1102{
60ee8be1 1103 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1104 args->errmsg, args->errmsg_len,
60ee8be1 1105 "ipv4-multicast", true);
2a1c520e
RW
1106}
1107
1108int isis_instance_multi_topology_ipv4_multicast_destroy(
60ee8be1 1109 struct nb_cb_destroy_args *args)
2a1c520e 1110{
60ee8be1 1111 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1112 args->errmsg, args->errmsg_len,
60ee8be1 1113 "ipv4-multicast", false);
2a1c520e
RW
1114}
1115
1116/*
1117 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
1118 */
1119int isis_instance_multi_topology_ipv4_multicast_overload_modify(
60ee8be1 1120 struct nb_cb_modify_args *args)
2a1c520e 1121{
60ee8be1 1122 return isis_multi_topology_overload_common(args->event, args->dnode,
2a1c520e
RW
1123 "ipv4-multicast");
1124}
1125
1126/*
1127 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
1128 */
1129int isis_instance_multi_topology_ipv4_management_create(
60ee8be1 1130 struct nb_cb_create_args *args)
2a1c520e 1131{
10bdc68f
RW
1132 return isis_multi_topology_common(args->event, args->dnode,
1133 args->errmsg, args->errmsg_len,
1134 "ipv4-mgmt", true);
2a1c520e
RW
1135}
1136
1137int isis_instance_multi_topology_ipv4_management_destroy(
60ee8be1 1138 struct nb_cb_destroy_args *args)
2a1c520e 1139{
10bdc68f
RW
1140 return isis_multi_topology_common(args->event, args->dnode,
1141 args->errmsg, args->errmsg_len,
1142 "ipv4-mgmt", false);
2a1c520e
RW
1143}
1144
1145/*
1146 * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
1147 */
1148int isis_instance_multi_topology_ipv4_management_overload_modify(
60ee8be1 1149 struct nb_cb_modify_args *args)
2a1c520e 1150{
60ee8be1
RW
1151 return isis_multi_topology_overload_common(args->event, args->dnode,
1152 "ipv4-mgmt");
2a1c520e
RW
1153}
1154
1155/*
1156 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
1157 */
1158int isis_instance_multi_topology_ipv6_unicast_create(
60ee8be1 1159 struct nb_cb_create_args *args)
2a1c520e 1160{
60ee8be1 1161 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1162 args->errmsg, args->errmsg_len,
60ee8be1 1163 "ipv6-unicast", true);
2a1c520e
RW
1164}
1165
1166int isis_instance_multi_topology_ipv6_unicast_destroy(
60ee8be1 1167 struct nb_cb_destroy_args *args)
2a1c520e 1168{
60ee8be1 1169 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1170 args->errmsg, args->errmsg_len,
60ee8be1 1171 "ipv6-unicast", false);
2a1c520e
RW
1172}
1173
1174/*
1175 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
1176 */
1177int isis_instance_multi_topology_ipv6_unicast_overload_modify(
60ee8be1 1178 struct nb_cb_modify_args *args)
2a1c520e 1179{
60ee8be1 1180 return isis_multi_topology_overload_common(args->event, args->dnode,
2a1c520e
RW
1181 "ipv6-unicast");
1182}
1183
1184/*
1185 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
1186 */
1187int isis_instance_multi_topology_ipv6_multicast_create(
60ee8be1 1188 struct nb_cb_create_args *args)
2a1c520e 1189{
60ee8be1 1190 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1191 args->errmsg, args->errmsg_len,
60ee8be1 1192 "ipv6-multicast", true);
2a1c520e
RW
1193}
1194
1195int isis_instance_multi_topology_ipv6_multicast_destroy(
60ee8be1 1196 struct nb_cb_destroy_args *args)
2a1c520e 1197{
60ee8be1 1198 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1199 args->errmsg, args->errmsg_len,
60ee8be1 1200 "ipv6-multicast", false);
2a1c520e
RW
1201}
1202
1203/*
1204 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
1205 */
1206int isis_instance_multi_topology_ipv6_multicast_overload_modify(
60ee8be1 1207 struct nb_cb_modify_args *args)
2a1c520e 1208{
60ee8be1 1209 return isis_multi_topology_overload_common(args->event, args->dnode,
2a1c520e
RW
1210 "ipv6-multicast");
1211}
1212
1213/*
1214 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
1215 */
1216int isis_instance_multi_topology_ipv6_management_create(
60ee8be1 1217 struct nb_cb_create_args *args)
2a1c520e 1218{
10bdc68f
RW
1219 return isis_multi_topology_common(args->event, args->dnode,
1220 args->errmsg, args->errmsg_len,
1221 "ipv6-mgmt", true);
2a1c520e
RW
1222}
1223
1224int isis_instance_multi_topology_ipv6_management_destroy(
60ee8be1 1225 struct nb_cb_destroy_args *args)
2a1c520e 1226{
10bdc68f
RW
1227 return isis_multi_topology_common(args->event, args->dnode,
1228 args->errmsg, args->errmsg_len,
1229 "ipv6-mgmt", false);
2a1c520e
RW
1230}
1231
1232/*
1233 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
1234 */
1235int isis_instance_multi_topology_ipv6_management_overload_modify(
60ee8be1 1236 struct nb_cb_modify_args *args)
2a1c520e 1237{
60ee8be1
RW
1238 return isis_multi_topology_overload_common(args->event, args->dnode,
1239 "ipv6-mgmt");
2a1c520e
RW
1240}
1241
1242/*
1243 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
1244 */
1245int isis_instance_multi_topology_ipv6_dstsrc_create(
60ee8be1 1246 struct nb_cb_create_args *args)
2a1c520e 1247{
60ee8be1 1248 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1249 args->errmsg, args->errmsg_len,
60ee8be1 1250 "ipv6-dstsrc", true);
2a1c520e
RW
1251}
1252
1253int isis_instance_multi_topology_ipv6_dstsrc_destroy(
60ee8be1 1254 struct nb_cb_destroy_args *args)
2a1c520e 1255{
60ee8be1 1256 return isis_multi_topology_common(args->event, args->dnode,
10bdc68f 1257 args->errmsg, args->errmsg_len,
60ee8be1 1258 "ipv6-dstsrc", false);
2a1c520e
RW
1259}
1260
1261/*
1262 * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
1263 */
1264int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
60ee8be1 1265 struct nb_cb_modify_args *args)
2a1c520e 1266{
60ee8be1
RW
1267 return isis_multi_topology_overload_common(args->event, args->dnode,
1268 "ipv6-dstsrc");
2a1c520e
RW
1269}
1270
1271/*
1272 * XPath: /frr-isisd:isis/instance/log-adjacency-changes
1273 */
60ee8be1 1274int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1275{
1276 struct isis_area *area;
60ee8be1 1277 bool log = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e 1278
60ee8be1 1279 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1280 return NB_OK;
1281
60ee8be1 1282 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1283 area->log_adj_changes = log ? 1 : 0;
1284
1285 return NB_OK;
1286}
1287
1288/*
1289 * XPath: /frr-isisd:isis/instance/mpls-te
1290 */
60ee8be1 1291int isis_instance_mpls_te_create(struct nb_cb_create_args *args)
2a1c520e
RW
1292{
1293 struct listnode *node;
1294 struct isis_area *area;
1295 struct isis_circuit *circuit;
1296
60ee8be1 1297 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1298 return NB_OK;
1299
60ee8be1 1300 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1301 if (area->mta == NULL) {
1302
1303 struct mpls_te_area *new;
1304
1305 zlog_debug("ISIS-TE(%s): Initialize MPLS Traffic Engineering",
1306 area->area_tag);
1307
1308 new = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_area));
1309
1310 /* Initialize MPLS_TE structure */
1311 new->status = enable;
1312 new->level = 0;
1313 new->inter_as = off;
1314 new->interas_areaid.s_addr = 0;
1315 new->router_id.s_addr = 0;
1316
1317 area->mta = new;
1318 } else {
1319 area->mta->status = enable;
1320 }
1321
1322 /* Update Extended TLVs according to Interface link parameters */
1323 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
1324 isis_link_params_update(circuit, circuit->interface);
1325
1326 /* Reoriginate STD_TE & GMPLS circuits */
1327 lsp_regenerate_schedule(area, area->is_type, 0);
1328
1329 return NB_OK;
1330}
1331
60ee8be1 1332int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
1333{
1334 struct listnode *node;
1335 struct isis_area *area;
1336 struct isis_circuit *circuit;
1337
60ee8be1 1338 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1339 return NB_OK;
1340
60ee8be1 1341 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1342 if (IS_MPLS_TE(area->mta))
1343 area->mta->status = disable;
1344 else
1345 return NB_OK;
1346
1347 /* Flush LSP if circuit engage */
1348 for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
1349 if (!IS_EXT_TE(circuit->ext))
1350 continue;
1351
1352 /* disable MPLS_TE Circuit keeping SR one's */
1353 if (IS_SUBTLV(circuit->ext, EXT_ADJ_SID))
1354 circuit->ext->status = EXT_ADJ_SID;
1355 else if (IS_SUBTLV(circuit->ext, EXT_LAN_ADJ_SID))
1356 circuit->ext->status = EXT_LAN_ADJ_SID;
1357 else
1358 circuit->ext->status = 0;
1359 }
1360
1361 /* Reoriginate STD_TE & GMPLS circuits */
1362 lsp_regenerate_schedule(area, area->is_type, 0);
1363
1364 zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
1365 area->area_tag);
1366
1367 return NB_OK;
1368}
1369
1370/*
1371 * XPath: /frr-isisd:isis/instance/mpls-te/router-address
1372 */
60ee8be1 1373int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1374{
1375 struct in_addr value;
1376 struct isis_area *area;
1377
60ee8be1 1378 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1379 return NB_OK;
1380
60ee8be1 1381 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1382 /* only proceed if MPLS-TE is enabled */
1383 if (!IS_MPLS_TE(area->mta))
1384 return NB_OK;
1385
1386 /* Update Area Router ID */
60ee8be1 1387 yang_dnode_get_ipv4(&value, args->dnode, NULL);
2a1c520e
RW
1388 area->mta->router_id.s_addr = value.s_addr;
1389
1390 /* And re-schedule LSP update */
1391 lsp_regenerate_schedule(area, area->is_type, 0);
1392
1393 return NB_OK;
1394}
1395
60ee8be1
RW
1396int isis_instance_mpls_te_router_address_destroy(
1397 struct nb_cb_destroy_args *args)
2a1c520e
RW
1398{
1399 struct isis_area *area;
1400
60ee8be1 1401 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1402 return NB_OK;
1403
60ee8be1 1404 area = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1405 /* only proceed if MPLS-TE is enabled */
1406 if (!IS_MPLS_TE(area->mta))
1407 return NB_OK;
1408
1409 /* Reset Area Router ID */
1410 area->mta->router_id.s_addr = INADDR_ANY;
1411
1412 /* And re-schedule LSP update */
1413 lsp_regenerate_schedule(area, area->is_type, 0);
1414
1415 return NB_OK;
1416}
1417
7e405d3b
RW
1418/*
1419 * XPath: /frr-isisd:isis/instance/segment-routing/enabled
1420 */
26f6acaf
RW
1421int isis_instance_segment_routing_enabled_modify(
1422 struct nb_cb_modify_args *args)
7e405d3b 1423{
26f6acaf
RW
1424 struct isis_area *area;
1425
1426 if (args->event != NB_EV_APPLY)
1427 return NB_OK;
1428
1429 area = nb_running_get_entry(args->dnode, NULL, true);
1430 area->srdb.config.enabled = yang_dnode_get_bool(args->dnode, NULL);
1431
1432 if (area->srdb.config.enabled) {
1433 if (IS_DEBUG_ISIS(DEBUG_EVENTS))
1434 zlog_debug("SR: Segment Routing: OFF -> ON");
1435
1436 if (isis_sr_start(area) == 0)
1437 area->srdb.enabled = true;
1438 } else {
1439 if (IS_DEBUG_ISIS(DEBUG_EVENTS))
1440 zlog_debug("SR: Segment Routing: ON -> OFF");
1441
1442 isis_sr_stop(area);
1443 area->srdb.enabled = false;
7e405d3b
RW
1444 }
1445
1446 return NB_OK;
1447}
1448
26f6acaf
RW
1449/*
1450 * XPath: /frr-isisd:isis/instance/segment-routing/srgb
1451 */
1452void isis_instance_segment_routing_srgb_apply_finish(
1453 struct nb_cb_apply_finish_args *args)
1454{
1455 struct isis_area *area;
1456 uint32_t lower_bound, upper_bound;
1457 int ret;
1458
1459 area = nb_running_get_entry(args->dnode, NULL, true);
1460 lower_bound = yang_dnode_get_uint32(args->dnode, "./lower-bound");
1461 upper_bound = yang_dnode_get_uint32(args->dnode, "./upper-bound");
1462
1463 ret = isis_sr_cfg_srgb_update(area, lower_bound, upper_bound);
1464 if (area->srdb.config.enabled) {
1465 if (ret == 0)
1466 area->srdb.enabled = true;
1467 else {
1468 isis_sr_stop(area);
1469 area->srdb.enabled = false;
1470 }
1471 }
1472}
1473
7e405d3b
RW
1474/*
1475 * XPath: /frr-isisd:isis/instance/segment-routing/srgb/lower-bound
1476 */
1477int isis_instance_segment_routing_srgb_lower_bound_modify(
26f6acaf 1478 struct nb_cb_modify_args *args)
7e405d3b 1479{
26f6acaf
RW
1480 uint32_t lower_bound = yang_dnode_get_uint32(args->dnode, NULL);
1481
1482 switch (args->event) {
7e405d3b 1483 case NB_EV_VALIDATE:
26f6acaf
RW
1484 if (!IS_MPLS_UNRESERVED_LABEL(lower_bound)) {
1485 zlog_warn("Invalid SRGB lower bound: %" PRIu32,
1486 lower_bound);
1487 return NB_ERR_VALIDATION;
1488 }
1489 break;
7e405d3b
RW
1490 case NB_EV_PREPARE:
1491 case NB_EV_ABORT:
1492 case NB_EV_APPLY:
7e405d3b
RW
1493 break;
1494 }
1495
1496 return NB_OK;
1497}
1498
1499/*
1500 * XPath: /frr-isisd:isis/instance/segment-routing/srgb/upper-bound
1501 */
1502int isis_instance_segment_routing_srgb_upper_bound_modify(
26f6acaf 1503 struct nb_cb_modify_args *args)
7e405d3b 1504{
26f6acaf
RW
1505 uint32_t upper_bound = yang_dnode_get_uint32(args->dnode, NULL);
1506
1507 switch (args->event) {
7e405d3b 1508 case NB_EV_VALIDATE:
26f6acaf
RW
1509 if (!IS_MPLS_UNRESERVED_LABEL(upper_bound)) {
1510 zlog_warn("Invalid SRGB upper bound: %" PRIu32,
1511 upper_bound);
1512 return NB_ERR_VALIDATION;
1513 }
1514 break;
7e405d3b
RW
1515 case NB_EV_PREPARE:
1516 case NB_EV_ABORT:
1517 case NB_EV_APPLY:
7e405d3b
RW
1518 break;
1519 }
1520
1521 return NB_OK;
1522}
1523
1524/*
1525 * XPath: /frr-isisd:isis/instance/segment-routing/msd/node-msd
1526 */
1527int isis_instance_segment_routing_msd_node_msd_modify(
26f6acaf 1528 struct nb_cb_modify_args *args)
7e405d3b 1529{
26f6acaf
RW
1530 struct isis_area *area;
1531
1532 if (args->event != NB_EV_APPLY)
1533 return NB_OK;
1534
1535 area = nb_running_get_entry(args->dnode, NULL, true);
1536 area->srdb.config.msd = yang_dnode_get_uint8(args->dnode, NULL);
c3f7b406
OD
1537
1538 /* Update and regenerate LSP */
1539 lsp_regenerate_schedule(area, area->is_type, 0);
7e405d3b
RW
1540
1541 return NB_OK;
1542}
1543
1544int isis_instance_segment_routing_msd_node_msd_destroy(
26f6acaf 1545 struct nb_cb_destroy_args *args)
7e405d3b 1546{
26f6acaf
RW
1547 struct isis_area *area;
1548
1549 if (args->event != NB_EV_APPLY)
1550 return NB_OK;
1551
1552 area = nb_running_get_entry(args->dnode, NULL, true);
1553 area->srdb.config.msd = 0;
c3f7b406
OD
1554
1555 /* Update and regenerate LSP */
1556 lsp_regenerate_schedule(area, area->is_type, 0);
7e405d3b
RW
1557
1558 return NB_OK;
1559}
1560
1561/*
1562 * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid
1563 */
1564int isis_instance_segment_routing_prefix_sid_map_prefix_sid_create(
26f6acaf 1565 struct nb_cb_create_args *args)
7e405d3b 1566{
26f6acaf
RW
1567 struct isis_area *area;
1568 struct prefix prefix;
1569 struct sr_prefix_cfg *pcfg;
1570
1571 if (args->event != NB_EV_APPLY)
1572 return NB_OK;
1573
1574 area = nb_running_get_entry(args->dnode, NULL, true);
1575 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
1576
1577 pcfg = isis_sr_cfg_prefix_add(area, &prefix);
1578 nb_running_set_entry(args->dnode, pcfg);
7e405d3b
RW
1579
1580 return NB_OK;
1581}
1582
1583int isis_instance_segment_routing_prefix_sid_map_prefix_sid_destroy(
26f6acaf 1584 struct nb_cb_destroy_args *args)
7e405d3b 1585{
26f6acaf
RW
1586 struct sr_prefix_cfg *pcfg;
1587 struct isis_area *area;
1588
1589 if (args->event != NB_EV_APPLY)
1590 return NB_OK;
1591
1592 pcfg = nb_running_unset_entry(args->dnode);
1593 area = pcfg->area;
1594 isis_sr_cfg_prefix_del(pcfg);
1595 lsp_regenerate_schedule(area, area->is_type, 0);
1596
1597 return NB_OK;
1598}
1599
1600int isis_instance_segment_routing_prefix_sid_map_prefix_sid_pre_validate(
1601 struct nb_cb_pre_validate_args *args)
1602{
1603 uint32_t srgb_lbound;
1604 uint32_t srgb_ubound;
1605 uint32_t srgb_range;
1606 uint32_t sid;
1607 enum sr_sid_value_type sid_type;
1608
1609 srgb_lbound = yang_dnode_get_uint32(args->dnode,
1610 "../../srgb/lower-bound");
1611 srgb_ubound = yang_dnode_get_uint32(args->dnode,
1612 "../../srgb/upper-bound");
1613 sid = yang_dnode_get_uint32(args->dnode, "./sid-value");
1614 sid_type = yang_dnode_get_enum(args->dnode, "./sid-value-type");
1615
1616 srgb_range = srgb_ubound - srgb_lbound + 1;
1617 switch (sid_type) {
1618 case SR_SID_VALUE_TYPE_INDEX:
1619 if (sid >= srgb_range) {
1620 zlog_warn("SID index %u falls outside local SRGB range",
1621 sid);
1622 return NB_ERR_VALIDATION;
1623 }
1624 break;
1625 case SR_SID_VALUE_TYPE_ABSOLUTE:
1626 if (!IS_MPLS_UNRESERVED_LABEL(sid)) {
1627 zlog_warn("Invalid absolute SID %u", sid);
1628 return NB_ERR_VALIDATION;
1629 }
7e405d3b
RW
1630 break;
1631 }
1632
1633 return NB_OK;
1634}
1635
26f6acaf
RW
1636void isis_instance_segment_routing_prefix_sid_map_prefix_sid_apply_finish(
1637 struct nb_cb_apply_finish_args *args)
1638{
1639 struct sr_prefix_cfg *pcfg;
1640 struct isis_area *area;
1641
1642 pcfg = nb_running_get_entry(args->dnode, NULL, true);
1643 area = pcfg->area;
1644 lsp_regenerate_schedule(area, area->is_type, 0);
1645}
1646
7e405d3b
RW
1647/*
1648 * XPath:
1649 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/sid-value-type
1650 */
1651int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_type_modify(
26f6acaf 1652 struct nb_cb_modify_args *args)
7e405d3b 1653{
26f6acaf
RW
1654 struct sr_prefix_cfg *pcfg;
1655
1656 if (args->event != NB_EV_APPLY)
1657 return NB_OK;
1658
1659 pcfg = nb_running_get_entry(args->dnode, NULL, true);
1660 pcfg->sid_type = yang_dnode_get_enum(args->dnode, NULL);
7e405d3b
RW
1661
1662 return NB_OK;
1663}
1664
1665/*
1666 * XPath:
1667 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/sid-value
1668 */
1669int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify(
26f6acaf 1670 struct nb_cb_modify_args *args)
7e405d3b 1671{
26f6acaf
RW
1672 struct sr_prefix_cfg *pcfg;
1673
1674 if (args->event != NB_EV_APPLY)
1675 return NB_OK;
1676
1677 pcfg = nb_running_get_entry(args->dnode, NULL, true);
1678 pcfg->sid = yang_dnode_get_uint32(args->dnode, NULL);
7e405d3b
RW
1679
1680 return NB_OK;
1681}
1682
1683/*
1684 * XPath:
1685 * /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/last-hop-behavior
1686 */
1687int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
26f6acaf 1688 struct nb_cb_modify_args *args)
7e405d3b 1689{
26f6acaf
RW
1690 struct sr_prefix_cfg *pcfg;
1691
1692 if (args->event != NB_EV_APPLY)
1693 return NB_OK;
1694
1695 pcfg = nb_running_get_entry(args->dnode, NULL, true);
1696 pcfg->last_hop_behavior = yang_dnode_get_enum(args->dnode, NULL);
7e405d3b
RW
1697
1698 return NB_OK;
1699}
1700
2a1c520e
RW
1701/*
1702 * XPath: /frr-interface:lib/interface/frr-isisd:isis
1703 */
60ee8be1 1704int lib_interface_isis_create(struct nb_cb_create_args *args)
2a1c520e
RW
1705{
1706 struct isis_area *area;
1707 struct interface *ifp;
1708 struct isis_circuit *circuit;
60ee8be1 1709 const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
2a1c520e
RW
1710 uint32_t min_mtu, actual_mtu;
1711
60ee8be1 1712 switch (args->event) {
2a1c520e
RW
1713 case NB_EV_PREPARE:
1714 case NB_EV_ABORT:
1715 break;
1716 case NB_EV_VALIDATE:
1717 /* check if interface mtu is sufficient. If the area has not
1718 * been created yet, assume default MTU for the area
1719 */
60ee8be1 1720 ifp = nb_running_get_entry(args->dnode, NULL, false);
2a1c520e
RW
1721 /* zebra might not know yet about the MTU - nothing we can do */
1722 if (!ifp || ifp->mtu == 0)
1723 break;
1724 actual_mtu =
1725 if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
1726 area = isis_area_lookup(area_tag);
1727 if (area)
1728 min_mtu = area->lsp_mtu;
1729 else
1730#ifndef FABRICD
1731 min_mtu = yang_get_default_uint16(
1732 "/frr-isisd:isis/instance/lsp/mtu");
1733#else
1734 min_mtu = DEFAULT_LSP_MTU;
1735#endif /* ifndef FABRICD */
1736 if (actual_mtu < min_mtu) {
10bdc68f
RW
1737 snprintf(args->errmsg, args->errmsg_len,
1738 "Interface %s has MTU %" PRIu32
1739 ", minimum MTU for the area is %" PRIu32 "",
1740 ifp->name, actual_mtu, min_mtu);
2a1c520e
RW
1741 return NB_ERR_VALIDATION;
1742 }
1743 break;
1744 case NB_EV_APPLY:
1745 area = isis_area_lookup(area_tag);
1746 /* The area should have already be created. We are
1747 * setting the priority of the global isis area creation
1748 * slightly lower, so it should be executed first, but I
1749 * cannot rely on that so here I have to check.
1750 */
1751 if (!area) {
1752 flog_err(
1753 EC_LIB_NB_CB_CONFIG_APPLY,
1754 "%s: attempt to create circuit for area %s before the area has been created",
1755 __func__, area_tag);
1756 abort();
1757 }
1758
60ee8be1 1759 ifp = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1760 circuit = isis_circuit_create(area, ifp);
1761 assert(circuit
1762 && (circuit->state == C_STATE_CONF
1763 || circuit->state == C_STATE_UP));
60ee8be1 1764 nb_running_set_entry(args->dnode, circuit);
2a1c520e
RW
1765 break;
1766 }
1767
1768 return NB_OK;
1769}
1770
60ee8be1 1771int lib_interface_isis_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
1772{
1773 struct isis_circuit *circuit;
1774
60ee8be1 1775 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1776 return NB_OK;
1777
60ee8be1 1778 circuit = nb_running_unset_entry(args->dnode);
2a1c520e
RW
1779 if (!circuit)
1780 return NB_ERR_INCONSISTENCY;
2a1c520e 1781
d38a3cb2
EDP
1782 /* disable both AFs for this circuit. this will also update the
1783 * CSM state by sending an ISIS_DISABLED signal. If there is no
1784 * area associated to the circuit there is nothing to do
1785 */
1786 if (circuit->area)
1787 isis_circuit_af_set(circuit, false, false);
2a1c520e
RW
1788 return NB_OK;
1789}
1790
1791/*
1792 * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
1793 */
60ee8be1 1794int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1795{
1796 struct isis_circuit *circuit;
1797 struct interface *ifp;
1798 struct vrf *vrf;
1799 const char *area_tag, *ifname, *vrfname;
1800
60ee8be1 1801 if (args->event == NB_EV_VALIDATE) {
2a1c520e
RW
1802 /* libyang doesn't like relative paths across module boundaries
1803 */
60ee8be1
RW
1804 ifname = yang_dnode_get_string(args->dnode->parent->parent,
1805 "./name");
1806 vrfname = yang_dnode_get_string(args->dnode->parent->parent,
1807 "./vrf");
2a1c520e
RW
1808 vrf = vrf_lookup_by_name(vrfname);
1809 assert(vrf);
1810 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1811 if (!ifp)
1812 return NB_OK;
1813 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
60ee8be1 1814 area_tag = yang_dnode_get_string(args->dnode, NULL);
2a1c520e
RW
1815 if (circuit && circuit->area && circuit->area->area_tag
1816 && strcmp(circuit->area->area_tag, area_tag)) {
10bdc68f
RW
1817 snprintf(args->errmsg, args->errmsg_len,
1818 "ISIS circuit is already defined on %s",
1819 circuit->area->area_tag);
2a1c520e
RW
1820 return NB_ERR_VALIDATION;
1821 }
1822 }
1823
1824 return NB_OK;
1825}
1826
1827/*
1828 * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
1829 */
60ee8be1 1830int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
2a1c520e 1831{
60ee8be1 1832 int circ_type = yang_dnode_get_enum(args->dnode, NULL);
2a1c520e
RW
1833 struct isis_circuit *circuit;
1834 struct interface *ifp;
1835 struct vrf *vrf;
1836 const char *ifname, *vrfname;
1837
60ee8be1 1838 switch (args->event) {
2a1c520e
RW
1839 case NB_EV_VALIDATE:
1840 /* libyang doesn't like relative paths across module boundaries
1841 */
60ee8be1
RW
1842 ifname = yang_dnode_get_string(args->dnode->parent->parent,
1843 "./name");
1844 vrfname = yang_dnode_get_string(args->dnode->parent->parent,
1845 "./vrf");
2a1c520e
RW
1846 vrf = vrf_lookup_by_name(vrfname);
1847 assert(vrf);
1848 ifp = if_lookup_by_name(ifname, vrf->vrf_id);
1849 if (!ifp)
1850 break;
1851 circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
1852 if (circuit && circuit->state == C_STATE_UP
1853 && circuit->area->is_type != IS_LEVEL_1_AND_2
1854 && circuit->area->is_type != circ_type) {
10bdc68f
RW
1855 snprintf(args->errmsg, args->errmsg_len,
1856 "Invalid circuit level for area %s",
1857 circuit->area->area_tag);
2a1c520e
RW
1858 return NB_ERR_VALIDATION;
1859 }
1860 break;
1861 case NB_EV_PREPARE:
1862 case NB_EV_ABORT:
1863 break;
1864 case NB_EV_APPLY:
60ee8be1 1865 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
1866 isis_circuit_is_type_set(circuit, circ_type);
1867 break;
1868 }
1869
1870 return NB_OK;
1871}
1872
1873/*
1874 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
1875 */
60ee8be1 1876int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1877{
1878 bool ipv4, ipv6;
1879 struct isis_circuit *circuit;
1880
60ee8be1 1881 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1882 return NB_OK;
1883
60ee8be1
RW
1884 circuit = nb_running_get_entry(args->dnode, NULL, true);
1885 ipv4 = yang_dnode_get_bool(args->dnode, NULL);
1886 ipv6 = yang_dnode_get_bool(args->dnode, "../ipv6-routing");
2a1c520e
RW
1887 isis_circuit_af_set(circuit, ipv4, ipv6);
1888
1889 return NB_OK;
1890}
1891
1892/*
1893 * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
1894 */
60ee8be1 1895int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1896{
1897 bool ipv4, ipv6;
1898 struct isis_circuit *circuit;
1899
60ee8be1 1900 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1901 return NB_OK;
1902
60ee8be1
RW
1903 circuit = nb_running_get_entry(args->dnode, NULL, true);
1904 ipv4 = yang_dnode_exists(args->dnode, "../ipv4-routing");
1905 ipv6 = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
1906 isis_circuit_af_set(circuit, ipv4, ipv6);
1907
1908 return NB_OK;
1909}
1910
1911/*
1912 * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring
1913 */
60ee8be1 1914int lib_interface_isis_bfd_monitoring_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
1915{
1916 struct isis_circuit *circuit;
1917 bool bfd_monitoring;
1918
60ee8be1 1919 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1920 return NB_OK;
1921
60ee8be1
RW
1922 circuit = nb_running_get_entry(args->dnode, NULL, true);
1923 bfd_monitoring = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
1924
1925 if (bfd_monitoring) {
1926 isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX,
1927 BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT,
1928 true);
1929 } else {
1930 isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
1931 bfd_info_free(&circuit->bfd_info);
1932 }
1933
1934 return NB_OK;
1935}
1936
1937/*
1938 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
1939 */
1940int lib_interface_isis_csnp_interval_level_1_modify(
60ee8be1 1941 struct nb_cb_modify_args *args)
2a1c520e
RW
1942{
1943 struct isis_circuit *circuit;
1944
60ee8be1 1945 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1946 return NB_OK;
1947
60ee8be1
RW
1948 circuit = nb_running_get_entry(args->dnode, NULL, true);
1949 circuit->csnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
1950
1951 return NB_OK;
1952}
1953
1954/*
1955 * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
1956 */
1957int lib_interface_isis_csnp_interval_level_2_modify(
60ee8be1 1958 struct nb_cb_modify_args *args)
2a1c520e
RW
1959{
1960 struct isis_circuit *circuit;
1961
60ee8be1 1962 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1963 return NB_OK;
1964
60ee8be1
RW
1965 circuit = nb_running_get_entry(args->dnode, NULL, true);
1966 circuit->csnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
1967
1968 return NB_OK;
1969}
1970
1971/*
1972 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
1973 */
1974int lib_interface_isis_psnp_interval_level_1_modify(
60ee8be1 1975 struct nb_cb_modify_args *args)
2a1c520e
RW
1976{
1977 struct isis_circuit *circuit;
1978
60ee8be1 1979 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1980 return NB_OK;
1981
60ee8be1
RW
1982 circuit = nb_running_get_entry(args->dnode, NULL, true);
1983 circuit->psnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
1984
1985 return NB_OK;
1986}
1987
1988/*
1989 * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
1990 */
1991int lib_interface_isis_psnp_interval_level_2_modify(
60ee8be1 1992 struct nb_cb_modify_args *args)
2a1c520e
RW
1993{
1994 struct isis_circuit *circuit;
1995
60ee8be1 1996 if (args->event != NB_EV_APPLY)
2a1c520e
RW
1997 return NB_OK;
1998
60ee8be1
RW
1999 circuit = nb_running_get_entry(args->dnode, NULL, true);
2000 circuit->psnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
2001
2002 return NB_OK;
2003}
2004
2005/*
2006 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
2007 */
60ee8be1 2008int lib_interface_isis_hello_padding_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2009{
2010 struct isis_circuit *circuit;
2011
60ee8be1 2012 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2013 return NB_OK;
2014
60ee8be1
RW
2015 circuit = nb_running_get_entry(args->dnode, NULL, true);
2016 circuit->pad_hellos = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
2017
2018 return NB_OK;
2019}
2020
2021/*
2022 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
2023 */
2024int lib_interface_isis_hello_interval_level_1_modify(
60ee8be1 2025 struct nb_cb_modify_args *args)
2a1c520e
RW
2026{
2027 struct isis_circuit *circuit;
2028 uint32_t interval;
2029
60ee8be1 2030 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2031 return NB_OK;
2032
60ee8be1
RW
2033 circuit = nb_running_get_entry(args->dnode, NULL, true);
2034 interval = yang_dnode_get_uint32(args->dnode, NULL);
2a1c520e
RW
2035 circuit->hello_interval[0] = interval;
2036
2037 return NB_OK;
2038}
2039
2040/*
2041 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
2042 */
2043int lib_interface_isis_hello_interval_level_2_modify(
60ee8be1 2044 struct nb_cb_modify_args *args)
2a1c520e
RW
2045{
2046 struct isis_circuit *circuit;
2047 uint32_t interval;
2048
60ee8be1 2049 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2050 return NB_OK;
2051
60ee8be1
RW
2052 circuit = nb_running_get_entry(args->dnode, NULL, true);
2053 interval = yang_dnode_get_uint32(args->dnode, NULL);
2a1c520e
RW
2054 circuit->hello_interval[1] = interval;
2055
2056 return NB_OK;
2057}
2058
2059/*
2060 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
2061 */
2062int lib_interface_isis_hello_multiplier_level_1_modify(
60ee8be1 2063 struct nb_cb_modify_args *args)
2a1c520e
RW
2064{
2065 struct isis_circuit *circuit;
2066 uint16_t multi;
2067
60ee8be1 2068 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2069 return NB_OK;
2070
60ee8be1
RW
2071 circuit = nb_running_get_entry(args->dnode, NULL, true);
2072 multi = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
2073 circuit->hello_multiplier[0] = multi;
2074
2075 return NB_OK;
2076}
2077
2078/*
2079 * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
2080 */
2081int lib_interface_isis_hello_multiplier_level_2_modify(
60ee8be1 2082 struct nb_cb_modify_args *args)
2a1c520e
RW
2083{
2084 struct isis_circuit *circuit;
2085 uint16_t multi;
2086
60ee8be1 2087 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2088 return NB_OK;
2089
60ee8be1
RW
2090 circuit = nb_running_get_entry(args->dnode, NULL, true);
2091 multi = yang_dnode_get_uint16(args->dnode, NULL);
2a1c520e
RW
2092 circuit->hello_multiplier[1] = multi;
2093
2094 return NB_OK;
2095}
2096
2097/*
2098 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
2099 */
60ee8be1 2100int lib_interface_isis_metric_level_1_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2101{
2102 struct isis_circuit *circuit;
2103 unsigned int met;
2104
60ee8be1 2105 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2106 return NB_OK;
2107
60ee8be1
RW
2108 circuit = nb_running_get_entry(args->dnode, NULL, true);
2109 met = yang_dnode_get_uint32(args->dnode, NULL);
2a1c520e
RW
2110 isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
2111
2112 return NB_OK;
2113}
2114
2115/*
2116 * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
2117 */
60ee8be1 2118int lib_interface_isis_metric_level_2_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2119{
2120 struct isis_circuit *circuit;
2121 unsigned int met;
2122
60ee8be1 2123 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2124 return NB_OK;
2125
60ee8be1
RW
2126 circuit = nb_running_get_entry(args->dnode, NULL, true);
2127 met = yang_dnode_get_uint32(args->dnode, NULL);
2a1c520e
RW
2128 isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
2129
2130 return NB_OK;
2131}
2132
2133/*
2134 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
2135 */
60ee8be1 2136int lib_interface_isis_priority_level_1_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2137{
2138 struct isis_circuit *circuit;
2139
60ee8be1 2140 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2141 return NB_OK;
2142
60ee8be1
RW
2143 circuit = nb_running_get_entry(args->dnode, NULL, true);
2144 circuit->priority[0] = yang_dnode_get_uint8(args->dnode, NULL);
2a1c520e
RW
2145
2146 return NB_OK;
2147}
2148
2149/*
2150 * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
2151 */
60ee8be1 2152int lib_interface_isis_priority_level_2_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2153{
2154 struct isis_circuit *circuit;
2155
60ee8be1 2156 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2157 return NB_OK;
2158
60ee8be1
RW
2159 circuit = nb_running_get_entry(args->dnode, NULL, true);
2160 circuit->priority[1] = yang_dnode_get_uint8(args->dnode, NULL);
2a1c520e
RW
2161
2162 return NB_OK;
2163}
2164
2165/*
2166 * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
2167 */
60ee8be1 2168int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2169{
2170 struct isis_circuit *circuit;
60ee8be1 2171 int net_type = yang_dnode_get_enum(args->dnode, NULL);
2a1c520e 2172
60ee8be1 2173 switch (args->event) {
2a1c520e 2174 case NB_EV_VALIDATE:
60ee8be1 2175 circuit = nb_running_get_entry(args->dnode, NULL, false);
2a1c520e
RW
2176 if (!circuit)
2177 break;
2178 if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
10bdc68f
RW
2179 snprintf(
2180 args->errmsg, args->errmsg_len,
2a1c520e
RW
2181 "Cannot change network type on loopback interface");
2182 return NB_ERR_VALIDATION;
2183 }
2184 if (net_type == CIRCUIT_T_BROADCAST
2185 && circuit->state == C_STATE_UP
2186 && !if_is_broadcast(circuit->interface)) {
10bdc68f
RW
2187 snprintf(
2188 args->errmsg, args->errmsg_len,
2a1c520e
RW
2189 "Cannot configure non-broadcast interface for broadcast operation");
2190 return NB_ERR_VALIDATION;
2191 }
2192 break;
2193 case NB_EV_PREPARE:
2194 case NB_EV_ABORT:
2195 break;
2196 case NB_EV_APPLY:
60ee8be1 2197 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
2198 isis_circuit_circ_type_set(circuit, net_type);
2199 break;
2200 }
2201
2202 return NB_OK;
2203}
2204
2205/*
2206 * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
2207 */
60ee8be1 2208int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2209{
2210 struct isis_circuit *circuit;
2211 struct isis_area *area;
2212 struct interface *ifp;
60ee8be1 2213 bool passive = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
2214
2215 /* validation only applies if we are setting passive to false */
60ee8be1
RW
2216 if (!passive && args->event == NB_EV_VALIDATE) {
2217 circuit = nb_running_get_entry(args->dnode, NULL, false);
2a1c520e
RW
2218 if (!circuit)
2219 return NB_OK;
2220 ifp = circuit->interface;
2221 if (!ifp)
2222 return NB_OK;
2223 if (if_is_loopback(ifp)) {
10bdc68f
RW
2224 snprintf(args->errmsg, args->errmsg_len,
2225 "Loopback is always passive");
2a1c520e
RW
2226 return NB_ERR_VALIDATION;
2227 }
2228 }
2229
60ee8be1 2230 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2231 return NB_OK;
2232
60ee8be1 2233 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
2234 if (circuit->state != C_STATE_UP) {
2235 circuit->is_passive = passive;
2236 } else {
2237 area = circuit->area;
2238 isis_csm_state_change(ISIS_DISABLE, circuit, area);
2239 circuit->is_passive = passive;
2240 isis_csm_state_change(ISIS_ENABLE, circuit, area);
2241 }
2242
2243 return NB_OK;
2244}
2245
2246/*
2247 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
2248 */
60ee8be1 2249int lib_interface_isis_password_create(struct nb_cb_create_args *args)
2a1c520e
RW
2250{
2251 return NB_OK;
2252}
2253
60ee8be1 2254int lib_interface_isis_password_destroy(struct nb_cb_destroy_args *args)
2a1c520e
RW
2255{
2256 struct isis_circuit *circuit;
2257
60ee8be1 2258 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2259 return NB_OK;
2260
60ee8be1 2261 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
2262 isis_circuit_passwd_unset(circuit);
2263
2264 return NB_OK;
2265}
2266
2267/*
2268 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
2269 */
60ee8be1 2270int lib_interface_isis_password_password_modify(struct nb_cb_modify_args *args)
2a1c520e
RW
2271{
2272 struct isis_circuit *circuit;
2273 const char *password;
2274
60ee8be1 2275 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2276 return NB_OK;
2277
60ee8be1
RW
2278 password = yang_dnode_get_string(args->dnode, NULL);
2279 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
2280
2281 isis_circuit_passwd_set(circuit, circuit->passwd.type, password);
2282
2283 return NB_OK;
2284}
2285
2286/*
2287 * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
2288 */
2289int lib_interface_isis_password_password_type_modify(
60ee8be1 2290 struct nb_cb_modify_args *args)
2a1c520e
RW
2291{
2292 struct isis_circuit *circuit;
2293 uint8_t pass_type;
2294
60ee8be1 2295 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2296 return NB_OK;
2297
60ee8be1
RW
2298 pass_type = yang_dnode_get_enum(args->dnode, NULL);
2299 circuit = nb_running_get_entry(args->dnode, NULL, true);
2a1c520e
RW
2300 circuit->passwd.type = pass_type;
2301
2302 return NB_OK;
2303}
2304
2305/*
2306 * XPath:
2307 * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
2308 */
2309int lib_interface_isis_disable_three_way_handshake_modify(
60ee8be1 2310 struct nb_cb_modify_args *args)
2a1c520e
RW
2311{
2312 struct isis_circuit *circuit;
2313
60ee8be1 2314 if (args->event != NB_EV_APPLY)
2a1c520e
RW
2315 return NB_OK;
2316
60ee8be1
RW
2317 circuit = nb_running_get_entry(args->dnode, NULL, true);
2318 circuit->disable_threeway_adj = yang_dnode_get_bool(args->dnode, NULL);
2a1c520e
RW
2319
2320 return NB_OK;
2321}
2322
2323/*
2324 * XPath:
2325 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
2326 */
2327static int lib_interface_isis_multi_topology_common(
10bdc68f
RW
2328 enum nb_event event, const struct lyd_node *dnode, char *errmsg,
2329 size_t errmsg_len, uint16_t mtid)
2a1c520e
RW
2330{
2331 struct isis_circuit *circuit;
2332 bool value;
2333
2334 switch (event) {
2335 case NB_EV_VALIDATE:
2336 circuit = nb_running_get_entry(dnode, NULL, false);
2337 if (circuit && circuit->area && circuit->area->oldmetric) {
10bdc68f
RW
2338 snprintf(
2339 errmsg, errmsg_len,
2a1c520e
RW
2340 "Multi topology IS-IS can only be used with wide metrics");
2341 return NB_ERR_VALIDATION;
2342 }
2343 break;
2344 case NB_EV_PREPARE:
2345 case NB_EV_ABORT:
2346 break;
2347 case NB_EV_APPLY:
2348 circuit = nb_running_get_entry(dnode, NULL, true);
2349 value = yang_dnode_get_bool(dnode, NULL);
2350 isis_circuit_mt_enabled_set(circuit, mtid, value);
2351 break;
2352 }
2353
2354 return NB_OK;
2355}
2356
2357int lib_interface_isis_multi_topology_ipv4_unicast_modify(
60ee8be1 2358 struct nb_cb_modify_args *args)
2a1c520e 2359{
60ee8be1 2360 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2361 args->event, args->dnode, args->errmsg, args->errmsg_len,
2362 ISIS_MT_IPV4_UNICAST);
2a1c520e
RW
2363}
2364
2365/*
2366 * XPath:
2367 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
2368 */
2369int lib_interface_isis_multi_topology_ipv4_multicast_modify(
60ee8be1 2370 struct nb_cb_modify_args *args)
2a1c520e 2371{
60ee8be1 2372 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2373 args->event, args->dnode, args->errmsg, args->errmsg_len,
2374 ISIS_MT_IPV4_MULTICAST);
2a1c520e
RW
2375}
2376
2377/*
2378 * XPath:
2379 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
2380 */
2381int lib_interface_isis_multi_topology_ipv4_management_modify(
60ee8be1 2382 struct nb_cb_modify_args *args)
2a1c520e 2383{
60ee8be1 2384 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2385 args->event, args->dnode, args->errmsg, args->errmsg_len,
2386 ISIS_MT_IPV4_MGMT);
2a1c520e
RW
2387}
2388
2389/*
2390 * XPath:
2391 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
2392 */
2393int lib_interface_isis_multi_topology_ipv6_unicast_modify(
60ee8be1 2394 struct nb_cb_modify_args *args)
2a1c520e 2395{
60ee8be1 2396 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2397 args->event, args->dnode, args->errmsg, args->errmsg_len,
2398 ISIS_MT_IPV6_UNICAST);
2a1c520e
RW
2399}
2400
2401/*
2402 * XPath:
2403 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
2404 */
2405int lib_interface_isis_multi_topology_ipv6_multicast_modify(
60ee8be1 2406 struct nb_cb_modify_args *args)
2a1c520e 2407{
60ee8be1 2408 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2409 args->event, args->dnode, args->errmsg, args->errmsg_len,
2410 ISIS_MT_IPV6_MULTICAST);
2a1c520e
RW
2411}
2412
2413/*
2414 * XPath:
2415 * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
2416 */
2417int lib_interface_isis_multi_topology_ipv6_management_modify(
60ee8be1 2418 struct nb_cb_modify_args *args)
2a1c520e 2419{
60ee8be1 2420 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2421 args->event, args->dnode, args->errmsg, args->errmsg_len,
2422 ISIS_MT_IPV6_MGMT);
2a1c520e
RW
2423}
2424
2425/*
2426 * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
2427 */
2428int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
60ee8be1 2429 struct nb_cb_modify_args *args)
2a1c520e 2430{
60ee8be1 2431 return lib_interface_isis_multi_topology_common(
10bdc68f
RW
2432 args->event, args->dnode, args->errmsg, args->errmsg_len,
2433 ISIS_MT_IPV6_DSTSRC);
2a1c520e 2434}