]>
Commit | Line | Data |
---|---|---|
2a1c520e RW |
1 | /* |
2 | * Copyright (C) 2018 Volta Networks | |
3 | * Emanuele Di Pascale | |
4 | * | |
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) | |
8 | * any later version. | |
9 | * | |
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 | |
13 | * more details. | |
14 | * | |
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 | |
18 | */ | |
19 | ||
20 | #include <zebra.h> | |
21 | ||
22 | #include "northbound.h" | |
23 | #include "linklist.h" | |
24 | ||
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" | |
30 | ||
31 | /* | |
32 | * XPath: /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency | |
33 | */ | |
60ee8be1 RW |
34 | const void *lib_interface_isis_adjacencies_adjacency_get_next( |
35 | struct nb_cb_get_next_args *args) | |
2a1c520e RW |
36 | { |
37 | struct interface *ifp; | |
38 | struct isis_circuit *circuit; | |
39 | struct isis_adjacency *adj, *adj_next = NULL; | |
40 | struct list *list; | |
41 | struct listnode *node, *node_next; | |
42 | ||
43 | /* Get first adjacency. */ | |
60ee8be1 RW |
44 | if (args->list_entry == NULL) { |
45 | ifp = (struct interface *)args->parent_list_entry; | |
2a1c520e RW |
46 | if (!ifp) |
47 | return NULL; | |
48 | ||
49 | circuit = circuit_scan_by_ifp(ifp); | |
50 | if (!circuit) | |
51 | return NULL; | |
52 | ||
53 | switch (circuit->circ_type) { | |
54 | case CIRCUIT_T_BROADCAST: | |
55 | for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; | |
56 | level++) { | |
57 | adj = listnode_head( | |
58 | circuit->u.bc.adjdb[level - 1]); | |
59 | if (adj) | |
60 | break; | |
61 | } | |
62 | break; | |
63 | case CIRCUIT_T_P2P: | |
64 | adj = circuit->u.p2p.neighbor; | |
65 | break; | |
66 | default: | |
67 | adj = NULL; | |
68 | break; | |
69 | } | |
70 | ||
71 | return adj; | |
72 | } | |
73 | ||
74 | /* Get next adjacency. */ | |
60ee8be1 | 75 | adj = (struct isis_adjacency *)args->list_entry; |
2a1c520e RW |
76 | circuit = adj->circuit; |
77 | switch (circuit->circ_type) { | |
78 | case CIRCUIT_T_BROADCAST: | |
79 | list = circuit->u.bc.adjdb[adj->level - 1]; | |
80 | node = listnode_lookup(list, adj); | |
81 | node_next = listnextnode(node); | |
82 | if (node_next) | |
83 | adj_next = listgetdata(node_next); | |
84 | else if (adj->level == ISIS_LEVEL1) { | |
85 | /* | |
86 | * Once we finish the L1 adjacencies, move to the L2 | |
87 | * adjacencies list. | |
88 | */ | |
89 | list = circuit->u.bc.adjdb[ISIS_LEVEL2 - 1]; | |
90 | adj_next = listnode_head(list); | |
91 | } | |
92 | break; | |
93 | case CIRCUIT_T_P2P: | |
94 | /* P2P circuits have at most one adjacency. */ | |
95 | default: | |
96 | break; | |
97 | } | |
98 | ||
99 | return adj_next; | |
100 | } | |
101 | ||
102 | /* | |
103 | * XPath: | |
104 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type | |
105 | */ | |
106 | struct yang_data * | |
107 | lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem( | |
60ee8be1 | 108 | struct nb_cb_get_elem_args *args) |
2a1c520e | 109 | { |
60ee8be1 | 110 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 111 | |
60ee8be1 | 112 | return yang_data_new_enum(args->xpath, adj->level); |
2a1c520e RW |
113 | } |
114 | ||
115 | /* | |
116 | * XPath: | |
117 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid | |
118 | */ | |
119 | struct yang_data * | |
120 | lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem( | |
60ee8be1 | 121 | struct nb_cb_get_elem_args *args) |
2a1c520e | 122 | { |
60ee8be1 | 123 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 124 | |
60ee8be1 | 125 | return yang_data_new_string(args->xpath, sysid_print(adj->sysid)); |
2a1c520e RW |
126 | } |
127 | ||
128 | /* | |
129 | * XPath: | |
130 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id | |
131 | */ | |
132 | struct yang_data * | |
133 | lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem( | |
60ee8be1 | 134 | struct nb_cb_get_elem_args *args) |
2a1c520e | 135 | { |
60ee8be1 | 136 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 137 | |
60ee8be1 | 138 | return yang_data_new_uint32(args->xpath, adj->circuit->circuit_id); |
2a1c520e RW |
139 | } |
140 | ||
141 | /* | |
142 | * XPath: | |
143 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa | |
144 | */ | |
145 | struct yang_data * | |
146 | lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem( | |
60ee8be1 | 147 | struct nb_cb_get_elem_args *args) |
2a1c520e | 148 | { |
60ee8be1 | 149 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 150 | |
60ee8be1 | 151 | return yang_data_new_string(args->xpath, snpa_print(adj->snpa)); |
2a1c520e RW |
152 | } |
153 | ||
154 | /* | |
155 | * XPath: | |
156 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer | |
157 | */ | |
158 | struct yang_data *lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem( | |
60ee8be1 | 159 | struct nb_cb_get_elem_args *args) |
2a1c520e | 160 | { |
60ee8be1 | 161 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 162 | |
60ee8be1 | 163 | return yang_data_new_uint16(args->xpath, adj->hold_time); |
2a1c520e RW |
164 | } |
165 | ||
166 | /* | |
167 | * XPath: | |
168 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-priority | |
169 | */ | |
170 | struct yang_data * | |
171 | lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem( | |
60ee8be1 | 172 | struct nb_cb_get_elem_args *args) |
2a1c520e | 173 | { |
60ee8be1 | 174 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 175 | |
60ee8be1 | 176 | return yang_data_new_uint8(args->xpath, adj->prio[adj->level - 1]); |
2a1c520e RW |
177 | } |
178 | ||
179 | /* | |
180 | * XPath: | |
181 | * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state | |
182 | */ | |
60ee8be1 RW |
183 | struct yang_data *lib_interface_isis_adjacencies_adjacency_state_get_elem( |
184 | struct nb_cb_get_elem_args *args) | |
2a1c520e | 185 | { |
60ee8be1 | 186 | const struct isis_adjacency *adj = args->list_entry; |
2a1c520e | 187 | |
60ee8be1 RW |
188 | return yang_data_new_string(args->xpath, |
189 | isis_adj_yang_state(adj->adj_state)); | |
2a1c520e RW |
190 | } |
191 | ||
192 | /* | |
193 | * XPath: | |
194 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes | |
195 | */ | |
196 | struct yang_data *lib_interface_isis_event_counters_adjacency_changes_get_elem( | |
60ee8be1 | 197 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
198 | { |
199 | struct interface *ifp; | |
200 | struct isis_circuit *circuit; | |
201 | ||
60ee8be1 | 202 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
203 | if (!ifp) |
204 | return NULL; | |
205 | ||
206 | circuit = circuit_scan_by_ifp(ifp); | |
207 | if (!circuit) | |
208 | return NULL; | |
209 | ||
60ee8be1 | 210 | return yang_data_new_uint32(args->xpath, circuit->adj_state_changes); |
2a1c520e RW |
211 | } |
212 | ||
213 | /* | |
214 | * XPath: | |
215 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number | |
216 | */ | |
217 | struct yang_data *lib_interface_isis_event_counters_adjacency_number_get_elem( | |
60ee8be1 | 218 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
219 | { |
220 | struct interface *ifp; | |
221 | struct isis_circuit *circuit; | |
222 | struct isis_adjacency *adj; | |
223 | struct listnode *node; | |
224 | uint32_t total = 0; | |
225 | ||
60ee8be1 | 226 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
227 | if (!ifp) |
228 | return NULL; | |
229 | ||
230 | circuit = circuit_scan_by_ifp(ifp); | |
231 | if (!circuit) | |
232 | return NULL; | |
233 | ||
234 | /* | |
235 | * TODO: keep track of the number of adjacencies instead of calculating | |
236 | * it on demand. | |
237 | */ | |
238 | switch (circuit->circ_type) { | |
239 | case CIRCUIT_T_BROADCAST: | |
240 | for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { | |
241 | for (ALL_LIST_ELEMENTS_RO( | |
242 | circuit->u.bc.adjdb[level - 1], node, adj)) | |
243 | total++; | |
244 | } | |
245 | break; | |
246 | case CIRCUIT_T_P2P: | |
247 | adj = circuit->u.p2p.neighbor; | |
248 | if (adj) | |
249 | total = 1; | |
250 | break; | |
251 | default: | |
252 | break; | |
253 | } | |
254 | ||
60ee8be1 | 255 | return yang_data_new_uint32(args->xpath, total); |
2a1c520e RW |
256 | } |
257 | ||
258 | /* | |
259 | * XPath: /frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails | |
260 | */ | |
60ee8be1 RW |
261 | struct yang_data *lib_interface_isis_event_counters_init_fails_get_elem( |
262 | struct nb_cb_get_elem_args *args) | |
2a1c520e RW |
263 | { |
264 | struct interface *ifp; | |
265 | struct isis_circuit *circuit; | |
266 | ||
60ee8be1 | 267 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
268 | if (!ifp) |
269 | return NULL; | |
270 | ||
271 | circuit = circuit_scan_by_ifp(ifp); | |
272 | if (!circuit) | |
273 | return NULL; | |
274 | ||
60ee8be1 | 275 | return yang_data_new_uint32(args->xpath, circuit->init_failures); |
2a1c520e RW |
276 | } |
277 | ||
278 | /* | |
279 | * XPath: | |
280 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects | |
281 | */ | |
282 | struct yang_data *lib_interface_isis_event_counters_adjacency_rejects_get_elem( | |
60ee8be1 | 283 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
284 | { |
285 | struct interface *ifp; | |
286 | struct isis_circuit *circuit; | |
287 | ||
60ee8be1 | 288 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
289 | if (!ifp) |
290 | return NULL; | |
291 | ||
292 | circuit = circuit_scan_by_ifp(ifp); | |
293 | if (!circuit) | |
294 | return NULL; | |
295 | ||
60ee8be1 | 296 | return yang_data_new_uint32(args->xpath, circuit->rej_adjacencies); |
2a1c520e RW |
297 | } |
298 | ||
299 | /* | |
300 | * XPath: | |
301 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch | |
302 | */ | |
303 | struct yang_data *lib_interface_isis_event_counters_id_len_mismatch_get_elem( | |
60ee8be1 | 304 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
305 | { |
306 | struct interface *ifp; | |
307 | struct isis_circuit *circuit; | |
308 | ||
60ee8be1 | 309 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
310 | if (!ifp) |
311 | return NULL; | |
312 | ||
313 | circuit = circuit_scan_by_ifp(ifp); | |
314 | if (!circuit) | |
315 | return NULL; | |
316 | ||
60ee8be1 | 317 | return yang_data_new_uint32(args->xpath, circuit->id_len_mismatches); |
2a1c520e RW |
318 | } |
319 | ||
320 | /* | |
321 | * XPath: | |
322 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/max-area-addresses-mismatch | |
323 | */ | |
324 | struct yang_data * | |
325 | lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem( | |
60ee8be1 | 326 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
327 | { |
328 | struct interface *ifp; | |
329 | struct isis_circuit *circuit; | |
330 | ||
60ee8be1 | 331 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
332 | if (!ifp) |
333 | return NULL; | |
334 | ||
335 | circuit = circuit_scan_by_ifp(ifp); | |
336 | if (!circuit) | |
337 | return NULL; | |
338 | ||
60ee8be1 RW |
339 | return yang_data_new_uint32(args->xpath, |
340 | circuit->max_area_addr_mismatches); | |
2a1c520e RW |
341 | } |
342 | ||
343 | /* | |
344 | * XPath: | |
345 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-type-fails | |
346 | */ | |
347 | struct yang_data * | |
348 | lib_interface_isis_event_counters_authentication_type_fails_get_elem( | |
60ee8be1 | 349 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
350 | { |
351 | struct interface *ifp; | |
352 | struct isis_circuit *circuit; | |
353 | ||
60ee8be1 | 354 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
355 | if (!ifp) |
356 | return NULL; | |
357 | ||
358 | circuit = circuit_scan_by_ifp(ifp); | |
359 | if (!circuit) | |
360 | return NULL; | |
361 | ||
60ee8be1 | 362 | return yang_data_new_uint32(args->xpath, circuit->auth_type_failures); |
2a1c520e RW |
363 | } |
364 | ||
365 | /* | |
366 | * XPath: | |
367 | * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-fails | |
368 | */ | |
369 | struct yang_data * | |
370 | lib_interface_isis_event_counters_authentication_fails_get_elem( | |
60ee8be1 | 371 | struct nb_cb_get_elem_args *args) |
2a1c520e RW |
372 | { |
373 | struct interface *ifp; | |
374 | struct isis_circuit *circuit; | |
375 | ||
60ee8be1 | 376 | ifp = (struct interface *)args->list_entry; |
2a1c520e RW |
377 | if (!ifp) |
378 | return NULL; | |
379 | ||
380 | circuit = circuit_scan_by_ifp(ifp); | |
381 | if (!circuit) | |
382 | return NULL; | |
383 | ||
60ee8be1 | 384 | return yang_data_new_uint32(args->xpath, circuit->auth_failures); |
2a1c520e | 385 | } |