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