2 * Copyright (C) 2018 Volta Networks
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "northbound.h"
25 #include "isisd/isisd.h"
26 #include "isisd/isis_nb.h"
27 #include "isisd/isis_circuit.h"
28 #include "isisd/isis_adjacency.h"
29 #include "isisd/isis_misc.h"
32 * XPath: /frr-interface:lib/interface/state/frr-isisd:isis
35 lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args
*args
)
37 struct interface
*ifp
;
38 struct isis_circuit
*circuit
;
40 ifp
= (struct interface
*)args
->list_entry
;
44 circuit
= circuit_scan_by_ifp(ifp
);
45 if (!circuit
|| !circuit
->area
)
48 return yang_data_new(args
->xpath
, NULL
);
53 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency
55 const void *lib_interface_state_isis_adjacencies_adjacency_get_next(
56 struct nb_cb_get_next_args
*args
)
58 struct interface
*ifp
;
59 struct isis_circuit
*circuit
;
60 struct isis_adjacency
*adj
= NULL
, *adj_next
= NULL
;
62 struct listnode
*node
, *node_next
;
64 /* Get first adjacency. */
65 if (args
->list_entry
== NULL
) {
66 ifp
= (struct interface
*)args
->parent_list_entry
;
70 circuit
= circuit_scan_by_ifp(ifp
);
74 switch (circuit
->circ_type
) {
75 case CIRCUIT_T_BROADCAST
:
76 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
;
80 adjdb
= circuit
->u
.bc
.adjdb
[level
- 1];
82 adj
= listnode_head(adjdb
);
89 adj
= circuit
->u
.p2p
.neighbor
;
98 /* Get next adjacency. */
99 adj
= (struct isis_adjacency
*)args
->list_entry
;
100 circuit
= adj
->circuit
;
101 switch (circuit
->circ_type
) {
102 case CIRCUIT_T_BROADCAST
:
103 list
= circuit
->u
.bc
.adjdb
[adj
->level
- 1];
104 node
= listnode_lookup(list
, adj
);
105 node_next
= listnextnode(node
);
107 adj_next
= listgetdata(node_next
);
108 else if (adj
->level
== ISIS_LEVEL1
) {
110 * Once we finish the L1 adjacencies, move to the L2
113 list
= circuit
->u
.bc
.adjdb
[ISIS_LEVEL2
- 1];
114 adj_next
= listnode_head(list
);
118 /* P2P circuits have at most one adjacency. */
128 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type
131 lib_interface_state_isis_adjacencies_adjacency_neighbor_sys_type_get_elem(
132 struct nb_cb_get_elem_args
*args
)
134 const struct isis_adjacency
*adj
= args
->list_entry
;
136 return yang_data_new_enum(args
->xpath
, adj
->level
);
141 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid
144 lib_interface_state_isis_adjacencies_adjacency_neighbor_sysid_get_elem(
145 struct nb_cb_get_elem_args
*args
)
147 const struct isis_adjacency
*adj
= args
->list_entry
;
149 return yang_data_new_string(args
->xpath
, sysid_print(adj
->sysid
));
154 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id
157 lib_interface_state_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem(
158 struct nb_cb_get_elem_args
*args
)
160 const struct isis_adjacency
*adj
= args
->list_entry
;
162 return yang_data_new_uint32(args
->xpath
, adj
->circuit
->circuit_id
);
167 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa
170 lib_interface_state_isis_adjacencies_adjacency_neighbor_snpa_get_elem(
171 struct nb_cb_get_elem_args
*args
)
173 const struct isis_adjacency
*adj
= args
->list_entry
;
175 return yang_data_new_string(args
->xpath
, snpa_print(adj
->snpa
));
180 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/hold-timer
183 lib_interface_state_isis_adjacencies_adjacency_hold_timer_get_elem(
184 struct nb_cb_get_elem_args
*args
)
186 const struct isis_adjacency
*adj
= args
->list_entry
;
188 return yang_data_new_uint16(args
->xpath
, adj
->hold_time
);
193 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/neighbor-priority
196 lib_interface_state_isis_adjacencies_adjacency_neighbor_priority_get_elem(
197 struct nb_cb_get_elem_args
*args
)
199 const struct isis_adjacency
*adj
= args
->list_entry
;
201 return yang_data_new_uint8(args
->xpath
, adj
->prio
[adj
->level
- 1]);
206 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/state
208 struct yang_data
*lib_interface_state_isis_adjacencies_adjacency_state_get_elem(
209 struct nb_cb_get_elem_args
*args
)
211 const struct isis_adjacency
*adj
= args
->list_entry
;
213 return yang_data_new_string(args
->xpath
,
214 isis_adj_yang_state(adj
->adj_state
));
219 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid
222 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_get_next(
223 struct nb_cb_get_next_args
*args
)
225 const struct isis_adjacency
*adj
= args
->parent_list_entry
;
226 const struct sr_adjacency
*sra
= args
->list_entry
, *sra_next
= NULL
;
227 struct listnode
*node
, *node_next
;
229 if (args
->list_entry
== NULL
)
230 sra_next
= listnode_head(adj
->adj_sids
);
232 node
= listnode_lookup(adj
->adj_sids
, sra
);
233 node_next
= listnextnode(node
);
235 sra_next
= listgetdata(node_next
);
243 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/af
246 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_af_get_elem(
247 struct nb_cb_get_elem_args
*args
)
249 const struct sr_adjacency
*sra
= args
->list_entry
;
251 switch (sra
->adj
->circuit
->circ_type
) {
252 case CIRCUIT_T_BROADCAST
:
253 /* Adjacency SID is not published with circuit type Broadcast */
256 return yang_data_new_uint8(args
->xpath
, sra
->u
.adj_sid
->family
);
264 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/value
267 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_value_get_elem(
268 struct nb_cb_get_elem_args
*args
)
270 const struct sr_adjacency
*sra
= args
->list_entry
;
272 switch (sra
->adj
->circuit
->circ_type
) {
273 case CIRCUIT_T_BROADCAST
:
274 /* Adjacency SID is not published with circuit type Broadcast */
277 return yang_data_new_uint32(args
->xpath
, sra
->u
.adj_sid
->sid
);
285 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/weight
288 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_weight_get_elem(
289 struct nb_cb_get_elem_args
*args
)
291 const struct sr_adjacency
*sra
= args
->list_entry
;
293 switch (sra
->adj
->circuit
->circ_type
) {
294 case CIRCUIT_T_BROADCAST
:
295 /* Adjacency SID is not published with circuit type Broadcast */
298 return yang_data_new_uint8(args
->xpath
, sra
->u
.adj_sid
->weight
);
306 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/protection-requested
309 lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_protection_requested_get_elem(
310 struct nb_cb_get_elem_args
*args
)
312 const struct sr_adjacency
*sra
= args
->list_entry
;
314 switch (sra
->adj
->circuit
->circ_type
) {
315 case CIRCUIT_T_BROADCAST
:
316 /* Adjacency SID is not published with circuit type Broadcast */
319 return yang_data_new_bool(args
->xpath
,
320 sra
->u
.adj_sid
->flags
&
321 EXT_SUBTLV_LINK_ADJ_SID_BFLG
);
329 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid
332 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_get_next(
333 struct nb_cb_get_next_args
*args
)
335 const struct isis_adjacency
*adj
= args
->parent_list_entry
;
336 const struct sr_adjacency
*sra
= args
->list_entry
, *sra_next
= NULL
;
337 struct listnode
*node
, *node_next
;
339 if (args
->list_entry
== NULL
)
340 sra_next
= listnode_head(adj
->adj_sids
);
342 node
= listnode_lookup(adj
->adj_sids
, sra
);
343 node_next
= listnextnode(node
);
345 sra_next
= listgetdata(node_next
);
353 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/af
356 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_af_get_elem(
357 struct nb_cb_get_elem_args
*args
)
359 const struct sr_adjacency
*sra
= args
->list_entry
;
361 switch (sra
->adj
->circuit
->circ_type
) {
362 case CIRCUIT_T_BROADCAST
:
363 return yang_data_new_uint8(args
->xpath
,
364 sra
->u
.ladj_sid
->family
);
366 /* LAN adjacency SID is not published with circuit type P2P */
375 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/value
378 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_value_get_elem(
379 struct nb_cb_get_elem_args
*args
)
381 const struct sr_adjacency
*sra
= args
->list_entry
;
383 switch (sra
->adj
->circuit
->circ_type
) {
384 case CIRCUIT_T_BROADCAST
:
385 return yang_data_new_uint32(args
->xpath
, sra
->u
.ladj_sid
->sid
);
387 /* LAN adjacency SID is not published with circuit type P2P */
396 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/weight
399 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_weight_get_elem(
400 struct nb_cb_get_elem_args
*args
)
402 const struct sr_adjacency
*sra
= args
->list_entry
;
404 switch (sra
->adj
->circuit
->circ_type
) {
405 case CIRCUIT_T_BROADCAST
:
406 return yang_data_new_uint8(args
->xpath
,
407 sra
->u
.ladj_sid
->weight
);
409 /* LAN adjacency SID is not published with circuit type P2P */
418 * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/protection-requested
421 lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_protection_requested_get_elem(
422 struct nb_cb_get_elem_args
*args
)
424 const struct sr_adjacency
*sra
= args
->list_entry
;
426 switch (sra
->adj
->circuit
->circ_type
) {
427 case CIRCUIT_T_BROADCAST
:
428 return yang_data_new_bool(args
->xpath
,
429 sra
->u
.ladj_sid
->flags
&
430 EXT_SUBTLV_LINK_ADJ_SID_BFLG
);
432 /* LAN adjacency SID is not published with circuit type P2P */
441 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-changes
444 lib_interface_state_isis_event_counters_adjacency_changes_get_elem(
445 struct nb_cb_get_elem_args
*args
)
447 struct interface
*ifp
;
448 struct isis_circuit
*circuit
;
450 ifp
= (struct interface
*)args
->list_entry
;
454 circuit
= circuit_scan_by_ifp(ifp
);
458 return yang_data_new_uint32(args
->xpath
, circuit
->adj_state_changes
);
463 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-number
466 lib_interface_state_isis_event_counters_adjacency_number_get_elem(
467 struct nb_cb_get_elem_args
*args
)
469 struct interface
*ifp
;
470 struct isis_circuit
*circuit
;
471 struct isis_adjacency
*adj
;
472 struct listnode
*node
;
475 ifp
= (struct interface
*)args
->list_entry
;
479 circuit
= circuit_scan_by_ifp(ifp
);
484 * TODO: keep track of the number of adjacencies instead of calculating
487 switch (circuit
->circ_type
) {
488 case CIRCUIT_T_BROADCAST
:
489 for (int level
= ISIS_LEVEL1
; level
<= ISIS_LEVELS
; level
++) {
490 for (ALL_LIST_ELEMENTS_RO(
491 circuit
->u
.bc
.adjdb
[level
- 1], node
, adj
))
496 adj
= circuit
->u
.p2p
.neighbor
;
504 return yang_data_new_uint32(args
->xpath
, total
);
509 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/init-fails
511 struct yang_data
*lib_interface_state_isis_event_counters_init_fails_get_elem(
512 struct nb_cb_get_elem_args
*args
)
514 struct interface
*ifp
;
515 struct isis_circuit
*circuit
;
517 ifp
= (struct interface
*)args
->list_entry
;
521 circuit
= circuit_scan_by_ifp(ifp
);
525 return yang_data_new_uint32(args
->xpath
, circuit
->init_failures
);
530 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-rejects
533 lib_interface_state_isis_event_counters_adjacency_rejects_get_elem(
534 struct nb_cb_get_elem_args
*args
)
536 struct interface
*ifp
;
537 struct isis_circuit
*circuit
;
539 ifp
= (struct interface
*)args
->list_entry
;
543 circuit
= circuit_scan_by_ifp(ifp
);
547 return yang_data_new_uint32(args
->xpath
, circuit
->rej_adjacencies
);
552 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/id-len-mismatch
555 lib_interface_state_isis_event_counters_id_len_mismatch_get_elem(
556 struct nb_cb_get_elem_args
*args
)
558 struct interface
*ifp
;
559 struct isis_circuit
*circuit
;
561 ifp
= (struct interface
*)args
->list_entry
;
565 circuit
= circuit_scan_by_ifp(ifp
);
569 return yang_data_new_uint32(args
->xpath
, circuit
->id_len_mismatches
);
574 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/max-area-addresses-mismatch
577 lib_interface_state_isis_event_counters_max_area_addresses_mismatch_get_elem(
578 struct nb_cb_get_elem_args
*args
)
580 struct interface
*ifp
;
581 struct isis_circuit
*circuit
;
583 ifp
= (struct interface
*)args
->list_entry
;
587 circuit
= circuit_scan_by_ifp(ifp
);
591 return yang_data_new_uint32(args
->xpath
,
592 circuit
->max_area_addr_mismatches
);
597 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/authentication-type-fails
600 lib_interface_state_isis_event_counters_authentication_type_fails_get_elem(
601 struct nb_cb_get_elem_args
*args
)
603 struct interface
*ifp
;
604 struct isis_circuit
*circuit
;
606 ifp
= (struct interface
*)args
->list_entry
;
610 circuit
= circuit_scan_by_ifp(ifp
);
614 return yang_data_new_uint32(args
->xpath
, circuit
->auth_type_failures
);
619 * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/authentication-fails
622 lib_interface_state_isis_event_counters_authentication_fails_get_elem(
623 struct nb_cb_get_elem_args
*args
)
625 struct interface
*ifp
;
626 struct isis_circuit
*circuit
;
628 ifp
= (struct interface
*)args
->list_entry
;
632 circuit
= circuit_scan_by_ifp(ifp
);
636 return yang_data_new_uint32(args
->xpath
, circuit
->auth_failures
);