1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018 Volta Networks
9 #include "northbound.h"
12 #include "isisd/isisd.h"
13 #include "isisd/isis_nb.h"
14 #include "isisd/isis_circuit.h"
15 #include "isisd/isis_adjacency.h"
16 #include "isisd/isis_misc.h"
19 * XPath: /frr-interface:lib/interface/state/frr-isisd:isis
22 lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args
*args
)
24 struct interface
*ifp
;
25 struct isis_circuit
*circuit
;
27 ifp
= (struct interface
*)args
->list_entry
;
31 circuit
= circuit_scan_by_ifp(ifp
);
32 if (!circuit
|| !circuit
->area
)
35 return yang_data_new(args
->xpath
, NULL
);
40 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency
42 const void *lib_interface_state_isis_adjacencies_adjacency_get_next(
43 struct nb_cb_get_next_args
*args
)
45 struct interface
*ifp
;
46 struct isis_circuit
*circuit
;
47 struct isis_adjacency
*adj
= NULL
, *adj_next
= NULL
;
49 struct listnode
*node
, *node_next
;
51 /* Get first adjacency. */
52 if (args
->list_entry
== NULL
) {
53 ifp
= (struct interface
*)args
->parent_list_entry
;
57 circuit
= circuit_scan_by_ifp(ifp
);
61 switch (circuit
->circ_type
) {
62 case CIRCUIT_T_BROADCAST
:
63 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
;
67 adjdb
= circuit
->u
.bc
.adjdb
[level
- 1];
69 adj
= listnode_head(adjdb
);
76 adj
= circuit
->u
.p2p
.neighbor
;
85 /* Get next adjacency. */
86 adj
= (struct isis_adjacency
*)args
->list_entry
;
87 circuit
= adj
->circuit
;
88 switch (circuit
->circ_type
) {
89 case CIRCUIT_T_BROADCAST
:
90 list
= circuit
->u
.bc
.adjdb
[adj
->level
- 1];
91 node
= listnode_lookup(list
, adj
);
92 node_next
= listnextnode(node
);
94 adj_next
= listgetdata(node_next
);
95 else if (adj
->level
== ISIS_LEVEL1
) {
97 * Once we finish the L1 adjacencies, move to the L2
100 list
= circuit
->u
.bc
.adjdb
[ISIS_LEVEL2
- 1];
101 adj_next
= listnode_head(list
);
105 /* P2P circuits have at most one adjacency. */
115 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type
118 lib_interface_state_isis_adjacencies_adjacency_neighbor_sys_type_get_elem(
119 struct nb_cb_get_elem_args
*args
)
121 const struct isis_adjacency
*adj
= args
->list_entry
;
123 return yang_data_new_enum(args
->xpath
, adj
->level
);
128 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid
131 lib_interface_state_isis_adjacencies_adjacency_neighbor_sysid_get_elem(
132 struct nb_cb_get_elem_args
*args
)
134 const struct isis_adjacency
*adj
= args
->list_entry
;
135 char xpath_value
[ISO_SYSID_STRLEN
];
137 snprintfrr(xpath_value
, ISO_SYSID_STRLEN
, "%pSY", adj
->sysid
);
139 return yang_data_new_string(args
->xpath
, xpath_value
);
144 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id
147 lib_interface_state_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem(
148 struct nb_cb_get_elem_args
*args
)
150 const struct isis_adjacency
*adj
= args
->list_entry
;
152 return yang_data_new_uint32(args
->xpath
, adj
->circuit
->circuit_id
);
157 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa
160 lib_interface_state_isis_adjacencies_adjacency_neighbor_snpa_get_elem(
161 struct nb_cb_get_elem_args
*args
)
163 const struct isis_adjacency
*adj
= args
->list_entry
;
164 char xpath_value
[ISO_SYSID_STRLEN
];
166 snprintfrr(xpath_value
, ISO_SYSID_STRLEN
, "%pSY", adj
->snpa
);
168 return yang_data_new_string(args
->xpath
, xpath_value
);
173 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/hold-timer
176 lib_interface_state_isis_adjacencies_adjacency_hold_timer_get_elem(
177 struct nb_cb_get_elem_args
*args
)
179 const struct isis_adjacency
*adj
= args
->list_entry
;
181 return yang_data_new_uint16(args
->xpath
, adj
->hold_time
);
186 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-priority
189 lib_interface_state_isis_adjacencies_adjacency_neighbor_priority_get_elem(
190 struct nb_cb_get_elem_args
*args
)
192 const struct isis_adjacency
*adj
= args
->list_entry
;
194 return yang_data_new_uint8(args
->xpath
, adj
->prio
[adj
->level
- 1]);
199 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/state
201 struct yang_data
*lib_interface_state_isis_adjacencies_adjacency_state_get_elem(
202 struct nb_cb_get_elem_args
*args
)
204 const struct isis_adjacency
*adj
= args
->list_entry
;
206 return yang_data_new_string(args
->xpath
,
207 isis_adj_yang_state(adj
->adj_state
));
212 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid
215 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_get_next(
216 struct nb_cb_get_next_args
*args
)
218 const struct isis_adjacency
*adj
= args
->parent_list_entry
;
219 const struct sr_adjacency
*sra
= args
->list_entry
, *sra_next
= NULL
;
220 struct listnode
*node
, *node_next
;
222 if (args
->list_entry
== NULL
)
223 sra_next
= listnode_head(adj
->adj_sids
);
225 node
= listnode_lookup(adj
->adj_sids
, sra
);
226 node_next
= listnextnode(node
);
228 sra_next
= listgetdata(node_next
);
236 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/af
239 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_af_get_elem(
240 struct nb_cb_get_elem_args
*args
)
242 const struct sr_adjacency
*sra
= args
->list_entry
;
244 switch (sra
->adj
->circuit
->circ_type
) {
245 case CIRCUIT_T_BROADCAST
:
246 /* Adjacency SID is not published with circuit type Broadcast */
249 return yang_data_new_uint8(args
->xpath
, sra
->u
.adj_sid
->family
);
257 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/value
260 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_value_get_elem(
261 struct nb_cb_get_elem_args
*args
)
263 const struct sr_adjacency
*sra
= args
->list_entry
;
265 switch (sra
->adj
->circuit
->circ_type
) {
266 case CIRCUIT_T_BROADCAST
:
267 /* Adjacency SID is not published with circuit type Broadcast */
270 return yang_data_new_uint32(args
->xpath
, sra
->u
.adj_sid
->sid
);
278 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/weight
281 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_weight_get_elem(
282 struct nb_cb_get_elem_args
*args
)
284 const struct sr_adjacency
*sra
= args
->list_entry
;
286 switch (sra
->adj
->circuit
->circ_type
) {
287 case CIRCUIT_T_BROADCAST
:
288 /* Adjacency SID is not published with circuit type Broadcast */
291 return yang_data_new_uint8(args
->xpath
, sra
->u
.adj_sid
->weight
);
299 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/protection-requested
302 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_protection_requested_get_elem(
303 struct nb_cb_get_elem_args
*args
)
305 const struct sr_adjacency
*sra
= args
->list_entry
;
307 switch (sra
->adj
->circuit
->circ_type
) {
308 case CIRCUIT_T_BROADCAST
:
309 /* Adjacency SID is not published with circuit type Broadcast */
312 return yang_data_new_bool(args
->xpath
,
313 sra
->u
.adj_sid
->flags
&
314 EXT_SUBTLV_LINK_ADJ_SID_BFLG
);
322 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid
325 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_get_next(
326 struct nb_cb_get_next_args
*args
)
328 const struct isis_adjacency
*adj
= args
->parent_list_entry
;
329 const struct sr_adjacency
*sra
= args
->list_entry
, *sra_next
= NULL
;
330 struct listnode
*node
, *node_next
;
332 if (args
->list_entry
== NULL
)
333 sra_next
= listnode_head(adj
->adj_sids
);
335 node
= listnode_lookup(adj
->adj_sids
, sra
);
336 node_next
= listnextnode(node
);
338 sra_next
= listgetdata(node_next
);
346 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/af
349 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_af_get_elem(
350 struct nb_cb_get_elem_args
*args
)
352 const struct sr_adjacency
*sra
= args
->list_entry
;
354 switch (sra
->adj
->circuit
->circ_type
) {
355 case CIRCUIT_T_BROADCAST
:
356 return yang_data_new_uint8(args
->xpath
,
357 sra
->u
.ladj_sid
->family
);
359 /* LAN adjacency SID is not published with circuit type P2P */
368 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/value
371 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_value_get_elem(
372 struct nb_cb_get_elem_args
*args
)
374 const struct sr_adjacency
*sra
= args
->list_entry
;
376 switch (sra
->adj
->circuit
->circ_type
) {
377 case CIRCUIT_T_BROADCAST
:
378 return yang_data_new_uint32(args
->xpath
, sra
->u
.ladj_sid
->sid
);
380 /* LAN adjacency SID is not published with circuit type P2P */
389 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/weight
392 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_weight_get_elem(
393 struct nb_cb_get_elem_args
*args
)
395 const struct sr_adjacency
*sra
= args
->list_entry
;
397 switch (sra
->adj
->circuit
->circ_type
) {
398 case CIRCUIT_T_BROADCAST
:
399 return yang_data_new_uint8(args
->xpath
,
400 sra
->u
.ladj_sid
->weight
);
402 /* LAN adjacency SID is not published with circuit type P2P */
411 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/protection-requested
414 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_protection_requested_get_elem(
415 struct nb_cb_get_elem_args
*args
)
417 const struct sr_adjacency
*sra
= args
->list_entry
;
419 switch (sra
->adj
->circuit
->circ_type
) {
420 case CIRCUIT_T_BROADCAST
:
421 return yang_data_new_bool(args
->xpath
,
422 sra
->u
.ladj_sid
->flags
&
423 EXT_SUBTLV_LINK_ADJ_SID_BFLG
);
425 /* LAN adjacency SID is not published with circuit type P2P */
434 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-changes
437 lib_interface_state_isis_event_counters_adjacency_changes_get_elem(
438 struct nb_cb_get_elem_args
*args
)
440 struct interface
*ifp
;
441 struct isis_circuit
*circuit
;
443 ifp
= (struct interface
*)args
->list_entry
;
447 circuit
= circuit_scan_by_ifp(ifp
);
451 return yang_data_new_uint32(args
->xpath
, circuit
->adj_state_changes
);
456 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-number
459 lib_interface_state_isis_event_counters_adjacency_number_get_elem(
460 struct nb_cb_get_elem_args
*args
)
462 struct interface
*ifp
;
463 struct isis_circuit
*circuit
;
464 struct isis_adjacency
*adj
;
465 struct listnode
*node
;
468 ifp
= (struct interface
*)args
->list_entry
;
472 circuit
= circuit_scan_by_ifp(ifp
);
477 * TODO: keep track of the number of adjacencies instead of calculating
480 switch (circuit
->circ_type
) {
481 case CIRCUIT_T_BROADCAST
:
482 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
; level
++) {
483 for (ALL_LIST_ELEMENTS_RO(
484 circuit
->u
.bc
.adjdb
[level
- 1], node
, adj
))
489 adj
= circuit
->u
.p2p
.neighbor
;
497 return yang_data_new_uint32(args
->xpath
, total
);
502 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/init-fails
504 struct yang_data
*lib_interface_state_isis_event_counters_init_fails_get_elem(
505 struct nb_cb_get_elem_args
*args
)
507 struct interface
*ifp
;
508 struct isis_circuit
*circuit
;
510 ifp
= (struct interface
*)args
->list_entry
;
514 circuit
= circuit_scan_by_ifp(ifp
);
518 return yang_data_new_uint32(args
->xpath
, circuit
->init_failures
);
523 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-rejects
526 lib_interface_state_isis_event_counters_adjacency_rejects_get_elem(
527 struct nb_cb_get_elem_args
*args
)
529 struct interface
*ifp
;
530 struct isis_circuit
*circuit
;
532 ifp
= (struct interface
*)args
->list_entry
;
536 circuit
= circuit_scan_by_ifp(ifp
);
540 return yang_data_new_uint32(args
->xpath
, circuit
->rej_adjacencies
);
545 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/id-len-mismatch
548 lib_interface_state_isis_event_counters_id_len_mismatch_get_elem(
549 struct nb_cb_get_elem_args
*args
)
551 struct interface
*ifp
;
552 struct isis_circuit
*circuit
;
554 ifp
= (struct interface
*)args
->list_entry
;
558 circuit
= circuit_scan_by_ifp(ifp
);
562 return yang_data_new_uint32(args
->xpath
, circuit
->id_len_mismatches
);
567 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/max-area-addresses-mismatch
570 lib_interface_state_isis_event_counters_max_area_addresses_mismatch_get_elem(
571 struct nb_cb_get_elem_args
*args
)
573 struct interface
*ifp
;
574 struct isis_circuit
*circuit
;
576 ifp
= (struct interface
*)args
->list_entry
;
580 circuit
= circuit_scan_by_ifp(ifp
);
584 return yang_data_new_uint32(args
->xpath
,
585 circuit
->max_area_addr_mismatches
);
590 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/authentication-type-fails
593 lib_interface_state_isis_event_counters_authentication_type_fails_get_elem(
594 struct nb_cb_get_elem_args
*args
)
596 struct interface
*ifp
;
597 struct isis_circuit
*circuit
;
599 ifp
= (struct interface
*)args
->list_entry
;
603 circuit
= circuit_scan_by_ifp(ifp
);
607 return yang_data_new_uint32(args
->xpath
, circuit
->auth_type_failures
);
612 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/authentication-fails
615 lib_interface_state_isis_event_counters_authentication_fails_get_elem(
616 struct nb_cb_get_elem_args
*args
)
618 struct interface
*ifp
;
619 struct isis_circuit
*circuit
;
621 ifp
= (struct interface
*)args
->list_entry
;
625 circuit
= circuit_scan_by_ifp(ifp
);
629 return yang_data_new_uint32(args
->xpath
, circuit
->auth_failures
);