1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2020 Volta Networks, Inc.
9 * This is minimal read-only implementations providing isisReadOnlyCompliance
14 #include <net-snmp/net-snmp-config.h>
15 #include <net-snmp/net-snmp-includes.h>
26 #include "lib/version.h"
27 #include "lib/zclient.h"
29 #include "isisd/isis_constants.h"
30 #include "isisd/isis_common.h"
31 #include "isisd/isis_flags.h"
32 #include "isisd/isis_circuit.h"
33 #include "isisd/isis_lsp.h"
34 #include "isisd/isis_pdu.h"
35 #include "isisd/isis_network.h"
36 #include "isisd/isis_misc.h"
37 #include "isisd/isis_constants.h"
38 #include "isisd/isis_adjacency.h"
39 #include "isisd/isis_dynhn.h"
40 #include "isisd/isis_te.h"
41 #include "isisd/isis_dr.h"
42 #include "isisd/isis_nb.h"
43 #include "isisd/isisd.h"
46 #define ISIS_MIB 1, 3, 6, 1, 2, 1, 138
48 #define ISIS_OBJECTS 1
49 #define ISIS_SYSTEM 1, 1
50 #define ISIS_SYSLEVEL 1, 2
51 #define ISIS_CIRC 1, 3
52 #define ISIS_CIRC_LEVEL_VALUES 1, 4
53 #define ISIS_COUNTERS 1, 5
54 #define ISIS_ISADJ 1, 6
56 /************************ isisSystemGroup ************************/
59 #define ISIS_SYS_OBJECT 1, 1, 1
60 #define ISIS_SYS_VERSION 1
61 #define ISIS_SYS_LEVELTYPE 2
63 #define ISIS_SYS_MAXPATHSPLITS 4
64 #define ISIS_SYS_MAXLSPGENINT 5
65 #define ISIS_SYS_POLLESHELLORATE 6
66 #define ISIS_SYS_WAITTIME 7
67 #define ISIS_SYS_ADMINSTATE 8
68 #define ISIS_SYS_L2TOL1LEAKING 9
69 #define ISIS_SYS_MAXAGE 10
70 #define ISIS_SYS_RECEIVELSPBUFFERSIZE 11
71 #define ISIS_SYS_PROTSUPPORTED 12
72 #define ISIS_SYS_NOTIFICATIONENABLE 13
74 /* isisManAreaAddrEntry */
75 #define ISIS_MANAREA_ADDRENTRY 1, 1, 2, 1
76 #define ISIS_MANAREA_ADDREXISTSTATE 2
78 /* isisAreaAddrEntry */
79 #define ISIS_AREA_ADDRENTRY 1, 1, 3, 1
80 #define ISIS_AREA_ADDR 1
82 /* isisSummAddrEntry */
83 #define ISIS_SUMM_ADDRENTRY 1, 1, 4, 1
84 #define ISIS_SUMM_ADDREXISTSTATE 4
85 #define ISIS_SUMM_ADDRMETRIC 5
86 #define ISIS_SUMM_ADDRFULLMETRIC 6
88 /* isisRedistributeAddrEntry */
89 #define ISIS_REDISTRIBUTE_ADDRENTRY 1, 1, 5, 1
90 #define ISIS_REDISTRIBUTE_ADDREXISTSTATE 3
93 #define ISIS_ROUTER_ENTRY 1, 1, 6, 1
94 #define ISIS_ROUTER_HOSTNAME 3
95 #define ISIS_ROUTER_ID 4
97 /* isisSysLevelTable */
98 #define ISIS_SYSLEVEL_ENTRY 1, 2, 1, 1
99 #define ISIS_SYSLEVEL_ORIGLSPBUFFSIZE 2
100 #define ISIS_SYSLEVEL_MINLSPGENINT 3
101 #define ISIS_SYSLEVEL_STATE 4
102 #define ISIS_SYSLEVEL_SETOVERLOAD 5
103 #define ISIS_SYSLEVEL_SETOVERLOADUNTIL 6
104 #define ISIS_SYSLEVEL_METRICSTYLE 7
105 #define ISIS_SYSLEVEL_SPFCONSIDERS 8
106 #define ISIS_SYSLEVEL_TEENABLED 9
109 /* isisSystemCounterEntry */
110 #define ISIS_SYSTEM_COUNTER_ENTRY 1, 5, 1, 1
111 #define ISIS_SYSSTAT_CORRLSPS 2
112 #define ISIS_SYSSTAT_AUTHTYPEFAILS 3
113 #define ISIS_SYSSTAT_AUTHFAILS 4
114 #define ISIS_SYSSTAT_LSPDBASEOLOADS 5
115 #define ISIS_SYSSTAT_MANADDRDROPFROMAREAS 6
116 #define ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS 7
117 #define ISIS_SYSSTAT_SEQNUMSKIPS 8
118 #define ISIS_SYSSTAT_OWNLSPPURGES 9
119 #define ISIS_SYSSTAT_IDFIELDLENMISMATCHES 10
120 #define ISIS_SYSSTAT_PARTCHANGES 11
121 #define ISIS_SYSSTAT_SPFRUNS 12
122 #define ISIS_SYSSTAT_LSPERRORS 13
125 /************************ isisCircuitGroup ************************/
127 /* Scalar directly under isisCirc */
128 #define ISIS_NEXTCIRC_INDEX 1
131 #define ISIS_CIRC_ENTRY 1, 3, 2, 1
132 #define ISIS_CIRC_IFINDEX 2
133 #define ISIS_CIRC_ADMINSTATE 3
134 #define ISIS_CIRC_EXISTSTATE 4
135 #define ISIS_CIRC_TYPE 5
136 #define ISIS_CIRC_EXTDOMAIN 6
137 #define ISIS_CIRC_LEVELTYPE 7
138 #define ISIS_CIRC_PASSIVECIRCUIT 8
139 #define ISIS_CIRC_MESHGROUPENABLED 9
140 #define ISIS_CIRC_MESHGROUP 10
141 #define ISIS_CIRC_SMALLHELLOS 11
142 #define ISIS_CIRC_LASTUPTIME 12
143 #define ISIS_CIRC_3WAYENABLED 13
144 #define ISIS_CIRC_EXTENDEDCIRCID 14
146 /* isisCircLevelEntry */
147 #define ISIS_CIRCLEVEL_ENTRY 1, 4, 1, 1
148 #define ISIS_CIRCLEVEL_METRIC 2
149 #define ISIS_CIRCLEVEL_WIDEMETRIC 3
150 #define ISIS_CIRCLEVEL_ISPRIORITY 4
151 #define ISIS_CIRCLEVEL_IDOCTET 5
152 #define ISIS_CIRCLEVEL_ID 6
153 #define ISIS_CIRCLEVEL_DESIS 7
154 #define ISIS_CIRCLEVEL_HELLOMULTIPLIER 8
155 #define ISIS_CIRCLEVEL_HELLOTIMER 9
156 #define ISIS_CIRCLEVEL_DRHELLOTIMER 10
157 #define ISIS_CIRCLEVEL_LSPTHROTTLE 11
158 #define ISIS_CIRCLEVEL_MINLSPRETRANSINT 12
159 #define ISIS_CIRCLEVEL_CSNPINTERVAL 13
160 #define ISIS_CIRCLEVEL_PARTSNPINTERVAL 14
162 /* isisCircuitCounterEntry */
163 #define ISIS_CIRC_COUNTER_ENTRY 1, 5, 2, 1
164 #define ISIS_CIRC_ADJCHANGES 2
165 #define ISIS_CIRC_NUMADJ 3
166 #define ISIS_CIRC_INITFAILS 4
167 #define ISIS_CIRC_REJADJS 5
168 #define ISIS_CIRC_IDFIELDLENMISMATCHES 6
169 #define ISIS_CIRC_MAXAREAADDRMISMATCHES 7
170 #define ISIS_CIRC_AUTHTYPEFAILS 8
171 #define ISIS_CIRC_AUTHFAILS 9
172 #define ISIS_CIRC_LANDESISCHANGES 10
175 /************************ isisISAdjGroup ************************/
178 #define ISIS_ISADJ_ENTRY 1, 6, 1, 1
179 #define ISIS_ISADJ_STATE 2
180 #define ISIS_ISADJ_3WAYSTATE 3
181 #define ISIS_ISADJ_NEIGHSNPAADDRESS 4
182 #define ISIS_ISADJ_NEIGHSYSTYPE 5
183 #define ISIS_ISADJ_NEIGHSYSID 6
184 #define ISIS_ISADJ_NBREXTENDEDCIRCID 7
185 #define ISIS_ISADJ_USAGE 8
186 #define ISIS_ISADJ_HOLDTIMER 9
187 #define ISIS_ISADJ_NEIGHPRIORITY 10
188 #define ISIS_ISADJ_LASTUPTIME 11
190 /* isisISAdjAreadAddrEntry */
191 #define ISIS_ISADJAREA_ADDRENTRY 1, 6, 2, 1
192 #define ISIS_ISADJAREA_ADDRESS 2
194 /* isisISAdjIPAddrEntry*/
195 #define ISIS_ISADJIPADDR_ENTRY 1, 6, 3, 1
196 #define ISIS_ISADJIPADDR_TYPE 2
197 #define ISIS_ISADJIPADDR_ADDRESS 3
200 /* isisISAdjProtSuppEntty */
202 #define ISIS_ISADJPROTSUPP_ENTRY 1, 6, 4, 1
203 #define ISIS_ISADJPROTSUPP_PROTOCOL 1
206 /************************ Trap data variables ************************/
207 #define ISIS_NOTIFICATION_ENTRY 1, 10, 1
208 #define ISIS_NOTIF_SYLELVELINDEX 1
209 #define ISIS_NOTIF_CIRCIFINDEX 2
210 #define ISIS_PDU_LSPID 3
211 #define ISIS_PDU_FRAGMENT 4
212 #define ISIS_PDU_FIELDLEN 5
213 #define ISIS_PDU_MAXAREAADDR 6
214 #define ISIS_PDU_PROTOVER 7
215 #define ISIS_PDU_LSPSIZE 8
216 #define ISIS_PDU_ORIGBUFFERSIZE 9
217 #define ISIS_PDU_BUFFERSIZE 10
218 #define ISIS_PDU_PROTSUPP 11
219 #define ISIS_ADJ_STATE 12
220 #define ISIS_ERROR_OFFSET 13
221 #define ISIS_ERROR_TLVTYPE 14
222 #define ISIS_NOTIF_AREAADDR 15
224 /************************ Traps ************************/
225 #define ISIS_NOTIFICATIONS ISIS_MIB, 0
226 #define ISIS_TRAP_DB_OVERLOAD 1
227 #define ISIS_TRAP_MAN_ADDR_DROP 2
228 #define ISIS_TRAP_CORRUPTED_LSP 3
229 #define ISIS_TRAP_LSP_EXCEED_MAX 4
230 #define ISIS_TRAP_ID_LEN_MISMATCH 5
231 #define ISIS_TRAP_MAX_AREA_ADDR_MISMATCH 6
232 #define ISIS_TRAP_OWN_LSP_PURGE 7
233 #define ISIS_TRAP_SEQNO_SKIPPED 8
234 #define ISIS_TRAP_AUTHEN_TYPE_FAILURE 9
235 #define ISIS_TRAP_AUTHEN_FAILURE 10
236 #define ISIS_TRAP_VERSION_SKEW 11
237 #define ISIS_TRAP_AREA_MISMATCH 12
238 #define ISIS_TRAP_REJ_ADJACENCY 13
239 #define ISIS_TRAP_LSP_TOO_LARGE 14
240 #define ISIS_TRAP_LSP_BUFFSIZE_MISMATCH 15
241 #define ISIS_TRAP_PROTSUPP_MISMATCH 16
242 #define ISIS_TRAP_ADJ_STATE_CHANGE 17
243 #define ISIS_TRAP_LSP_ERROR 18
245 /* Change this definition if number of traps changes */
246 #define ISIS_TRAP_LAST_TRAP ISIS_TRAP_LSP_ERROR + 1
248 #define ISIS_SNMP_TRAP_VAR 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0
251 /* SNMP value hack. */
252 #define COUNTER32 ASN_COUNTER
253 #define INTEGER ASN_INTEGER
254 #define UNSIGNED32 ASN_GAUGE
255 #define TIMESTAMP ASN_TIMETICKS
256 #define TIMETICKS ASN_TIMETICKS
257 #define STRING ASN_OCTET_STR
259 /* Declare static local variables for convenience. */
263 * Define time function, it serves two purposes
264 * 1. Uses unint32_t for unix time and encapsulates
265 * sing extension issues in conversion from time_t
267 * 2. I could be replaced in unit test environment
270 /* ISIS-MIB instances. */
271 static oid isis_oid
[] = {ISIS_MIB
};
273 /* SNMP trap variable */
274 static oid isis_snmp_trap_var
[] = {ISIS_SNMP_TRAP_VAR
};
276 /* SNMP trap values (others are calculated on the fly */
277 static oid isis_snmp_notifications
[] = {ISIS_NOTIFICATIONS
};
278 static oid isis_snmp_trap_val_db_overload
[] = {ISIS_NOTIFICATIONS
,
279 ISIS_TRAP_DB_OVERLOAD
};
280 static oid isis_snmp_trap_val_lsp_exceed_max
[] = {ISIS_NOTIFICATIONS
,
281 ISIS_TRAP_LSP_EXCEED_MAX
};
282 static oid isis_snmp_trap_val_area_mismatch
[] = {ISIS_NOTIFICATIONS
,
283 ISIS_TRAP_AREA_MISMATCH
};
284 static oid isis_snmp_trap_val_lsp_error
[] = {ISIS_NOTIFICATIONS
,
285 ISIS_TRAP_LSP_ERROR
};
288 * Trap vars under 'isisNotifications': note: we use full names of variables
291 static oid isis_snmp_trap_data_var_sys_level_index
[] = {
292 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_SYLELVELINDEX
, 0};
293 static oid isis_snmp_trap_data_var_circ_if_index
[] = {
294 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_CIRCIFINDEX
, 0};
295 static oid isis_snmp_trap_data_var_pdu_lsp_id
[] = {
296 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPID
, 0};
297 static oid isis_snmp_trap_data_var_pdu_fragment
[] = {
298 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FRAGMENT
, 0};
299 static oid isis_snmp_trap_data_var_pdu_field_len
[] = {
300 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FIELDLEN
, 0};
301 static oid isis_snmp_trap_data_var_pdu_max_area_addr
[] = {
302 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_MAXAREAADDR
, 0};
303 static oid isis_snmp_trap_data_var_pdu_proto_ver
[] = {
304 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_PROTOVER
, 0};
305 static oid isis_snmp_trap_data_var_pdu_lsp_size
[] = {
306 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPSIZE
, 0};
307 static oid isis_snmp_trap_data_var_adj_state
[] = {
308 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ADJ_STATE
, 0};
309 static oid isis_snmp_trap_data_var_error_offset
[] = {
310 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_OFFSET
, 0};
311 static oid isis_snmp_trap_data_var_error_tlv_type
[] = {
312 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_TLVTYPE
, 0};
315 * Other variables used by traps: note we use full names of variables and
316 * reserve space for index
318 static oid isis_snmp_trap_data_var_sys_level_state
[] = {
319 ISIS_MIB
, ISIS_SYSLEVEL_ENTRY
, ISIS_SYSLEVEL_STATE
, 0};
321 /* Throttle time values for traps */
322 static time_t isis_snmp_trap_timestamp
[ISIS_TRAP_LAST_TRAP
]; /* ?? 1 */
324 /* Max len of raw-pdu in traps */
325 #define ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN (64)
328 * Just to save on typing we have a shortcut structure
329 * to specify mib layout as prefix/leaf combination
331 #define ISIS_SNMP_PREF_LEN_MAX 10
332 struct isis_var_prefix
{
333 FindVarMethod
*findVar
;
334 uint8_t ivd_pref_len
;
335 oid ivd_pref
[ISIS_SNMP_PREF_LEN_MAX
];
339 /* Find-val functions */
340 static uint8_t *isis_snmp_find_sys_object(struct variable
*, oid
*, size_t *,
341 int, size_t *, WriteMethod
**);
343 static uint8_t *isis_snmp_find_man_area(struct variable
*, oid
*, size_t *, int,
344 size_t *, WriteMethod
**);
346 static uint8_t *isis_snmp_find_area_addr(struct variable
*, oid
*, size_t *,
347 int, size_t *, WriteMethod
**);
349 static uint8_t *isis_snmp_find_summ_addr(struct variable
*, oid
*, size_t *,
350 int, size_t *, WriteMethod
**);
352 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*, oid
*,
353 size_t *, int, size_t *,
356 static uint8_t *isis_snmp_find_router(struct variable
*, oid
*, size_t *, int,
357 size_t *, WriteMethod
**);
359 static uint8_t *isis_snmp_find_sys_level(struct variable
*, oid
*, size_t *,
360 int, size_t *, WriteMethod
**);
362 static uint8_t *isis_snmp_find_system_counter(struct variable
*, oid
*,
363 size_t *, int, size_t *,
366 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*, oid
*,
367 size_t *, int, size_t *,
370 static uint8_t *isis_snmp_find_circ(struct variable
*, oid
*, size_t *, int,
371 size_t *, WriteMethod
**);
373 static uint8_t *isis_snmp_find_circ_level(struct variable
*, oid
*, size_t *,
374 int, size_t *, WriteMethod
**);
376 static uint8_t *isis_snmp_find_circ_counter(struct variable
*, oid
*, size_t *,
377 int, size_t *, WriteMethod
**);
379 static uint8_t *isis_snmp_find_isadj(struct variable
*, oid
*, size_t *, int,
380 size_t *, WriteMethod
**);
382 static uint8_t *isis_snmp_find_isadj_area(struct variable
*, oid
*, size_t *,
383 int, size_t *, WriteMethod
**);
385 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*, oid
*, size_t *,
386 int, size_t *, WriteMethod
**);
388 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*, oid
*,
389 size_t *, int, size_t *,
393 * Just to save on typing we have a shortcut structure
394 * to specify mib layout, we populate the rest of the data
395 * during initialization
397 #define ISIS_PREF_LEN_MAX (6)
399 struct isis_func_to_prefix
{
400 FindVarMethod
*ihtp_func
;
401 oid ihtp_pref_oid
[ISIS_PREF_LEN_MAX
];
402 uint8_t ihtp_pref_len
;
405 static struct isis_func_to_prefix isis_func_to_prefix_arr
[] = {
406 {isis_snmp_find_sys_object
, {ISIS_SYS_OBJECT
}, 3},
407 {isis_snmp_find_man_area
, {ISIS_MANAREA_ADDRENTRY
}, 4},
408 {isis_snmp_find_area_addr
, {ISIS_AREA_ADDRENTRY
}, 4},
409 {isis_snmp_find_summ_addr
, {ISIS_SUMM_ADDRENTRY
}, 4},
410 {isis_snmp_find_redistribute_addr
, {ISIS_REDISTRIBUTE_ADDRENTRY
}, 4},
411 {isis_snmp_find_router
, {ISIS_ROUTER_ENTRY
}, 4},
412 {isis_snmp_find_sys_level
, {ISIS_SYSLEVEL_ENTRY
}, 4},
413 {isis_snmp_find_system_counter
, {ISIS_SYSTEM_COUNTER_ENTRY
}, 4},
414 {isis_snmp_find_next_circ_index
, {ISIS_CIRC
}, 2},
415 {isis_snmp_find_circ
, {ISIS_CIRC_ENTRY
}, 4},
416 {isis_snmp_find_circ_level
, {ISIS_CIRCLEVEL_ENTRY
}, 4},
417 {isis_snmp_find_circ_counter
, {ISIS_CIRC_COUNTER_ENTRY
}, 4},
418 {isis_snmp_find_isadj
, {ISIS_ISADJ_ENTRY
}, 4},
419 {isis_snmp_find_isadj_area
, {ISIS_ISADJAREA_ADDRENTRY
}, 4},
420 {isis_snmp_find_isadj_ipaddr
, {ISIS_ISADJIPADDR_ENTRY
}, 4},
421 {isis_snmp_find_isadj_prot_supp
, {ISIS_ISADJPROTSUPP_ENTRY
}, 4},
423 static size_t isis_func_to_prefix_count
= array_size(isis_func_to_prefix_arr
);
425 static struct variable isis_var_arr
[] = {
426 {ISIS_SYS_VERSION
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
427 {ISIS_SYS_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
428 {ISIS_SYS_ID
, STRING
, RONLY
, isis_snmp_find_sys_object
},
429 {ISIS_SYS_MAXPATHSPLITS
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
430 {ISIS_SYS_MAXLSPGENINT
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
431 {ISIS_SYS_POLLESHELLORATE
, UNSIGNED32
, RONLY
,
432 isis_snmp_find_sys_object
},
433 {ISIS_SYS_WAITTIME
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
434 {ISIS_SYS_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
435 {ISIS_SYS_L2TOL1LEAKING
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
436 {ISIS_SYS_MAXAGE
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
437 {ISIS_SYS_RECEIVELSPBUFFERSIZE
, UNSIGNED32
, RONLY
,
438 isis_snmp_find_sys_object
},
439 {ISIS_SYS_PROTSUPPORTED
, STRING
, RONLY
, isis_snmp_find_sys_object
},
440 {ISIS_SYS_NOTIFICATIONENABLE
, INTEGER
, RONLY
,
441 isis_snmp_find_sys_object
},
442 {ISIS_MANAREA_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_man_area
},
443 {ISIS_AREA_ADDR
, STRING
, RONLY
, isis_snmp_find_area_addr
},
444 {ISIS_SUMM_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_summ_addr
},
445 {ISIS_SUMM_ADDRMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
446 {ISIS_SUMM_ADDRFULLMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
447 {ISIS_REDISTRIBUTE_ADDREXISTSTATE
, INTEGER
, RONLY
,
448 isis_snmp_find_redistribute_addr
},
449 {ISIS_ROUTER_HOSTNAME
, STRING
, RONLY
, isis_snmp_find_router
},
450 {ISIS_ROUTER_ID
, UNSIGNED32
, RONLY
, isis_snmp_find_router
},
451 {ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
, UNSIGNED32
, RONLY
,
452 isis_snmp_find_sys_level
},
453 {ISIS_SYSLEVEL_MINLSPGENINT
, UNSIGNED32
, RONLY
,
454 isis_snmp_find_sys_level
},
455 {ISIS_SYSLEVEL_STATE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
456 {ISIS_SYSLEVEL_SETOVERLOAD
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
457 {ISIS_SYSLEVEL_SETOVERLOADUNTIL
, UNSIGNED32
, RONLY
,
458 isis_snmp_find_sys_level
},
459 {ISIS_SYSLEVEL_METRICSTYLE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
460 {ISIS_SYSLEVEL_SPFCONSIDERS
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
461 {ISIS_SYSLEVEL_TEENABLED
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
462 {ISIS_SYSSTAT_CORRLSPS
, COUNTER32
, RONLY
,
463 isis_snmp_find_system_counter
},
464 {ISIS_SYSSTAT_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
465 isis_snmp_find_system_counter
},
466 {ISIS_SYSSTAT_AUTHFAILS
, COUNTER32
, RONLY
,
467 isis_snmp_find_system_counter
},
468 {ISIS_SYSSTAT_LSPDBASEOLOADS
, COUNTER32
, RONLY
,
469 isis_snmp_find_system_counter
},
470 {ISIS_SYSSTAT_MANADDRDROPFROMAREAS
, COUNTER32
, RONLY
,
471 isis_snmp_find_system_counter
},
472 {ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
, COUNTER32
, RONLY
,
473 isis_snmp_find_system_counter
},
474 {ISIS_SYSSTAT_SEQNUMSKIPS
, COUNTER32
, RONLY
,
475 isis_snmp_find_system_counter
},
476 {ISIS_SYSSTAT_OWNLSPPURGES
, COUNTER32
, RONLY
,
477 isis_snmp_find_system_counter
},
478 {ISIS_SYSSTAT_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
479 isis_snmp_find_system_counter
},
480 {ISIS_SYSSTAT_PARTCHANGES
, COUNTER32
, RONLY
,
481 isis_snmp_find_system_counter
},
482 {ISIS_SYSSTAT_SPFRUNS
, COUNTER32
, RONLY
, isis_snmp_find_system_counter
},
483 {ISIS_SYSSTAT_LSPERRORS
, COUNTER32
, RONLY
,
484 isis_snmp_find_system_counter
},
485 {ISIS_NEXTCIRC_INDEX
, UNSIGNED32
, RONLY
,
486 isis_snmp_find_next_circ_index
},
487 {ISIS_CIRC_IFINDEX
, INTEGER
, RONLY
, isis_snmp_find_circ
},
488 {ISIS_CIRC_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
489 {ISIS_CIRC_EXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
490 {ISIS_CIRC_TYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
491 {ISIS_CIRC_EXTDOMAIN
, INTEGER
, RONLY
, isis_snmp_find_circ
},
492 {ISIS_CIRC_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
493 {ISIS_CIRC_PASSIVECIRCUIT
, INTEGER
, RONLY
, isis_snmp_find_circ
},
494 {ISIS_CIRC_MESHGROUPENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
495 {ISIS_CIRC_MESHGROUP
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
496 {ISIS_CIRC_SMALLHELLOS
, INTEGER
, RONLY
, isis_snmp_find_circ
},
497 {ISIS_CIRC_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_circ
},
498 {ISIS_CIRC_3WAYENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
499 {ISIS_CIRC_EXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
500 {ISIS_CIRCLEVEL_METRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
501 {ISIS_CIRCLEVEL_WIDEMETRIC
, UNSIGNED32
, RONLY
,
502 isis_snmp_find_circ_level
},
503 {ISIS_CIRCLEVEL_ISPRIORITY
, UNSIGNED32
, RONLY
,
504 isis_snmp_find_circ_level
},
505 {ISIS_CIRCLEVEL_IDOCTET
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
506 {ISIS_CIRCLEVEL_ID
, STRING
, RONLY
, isis_snmp_find_circ_level
},
507 {ISIS_CIRCLEVEL_DESIS
, STRING
, RONLY
, isis_snmp_find_circ_level
},
508 {ISIS_CIRCLEVEL_HELLOMULTIPLIER
, UNSIGNED32
, RONLY
,
509 isis_snmp_find_circ_level
},
510 {ISIS_CIRCLEVEL_HELLOTIMER
, UNSIGNED32
, RONLY
,
511 isis_snmp_find_circ_level
},
512 {ISIS_CIRCLEVEL_DRHELLOTIMER
, UNSIGNED32
, RONLY
,
513 isis_snmp_find_circ_level
},
514 {ISIS_CIRCLEVEL_LSPTHROTTLE
, UNSIGNED32
, RONLY
,
515 isis_snmp_find_circ_level
},
516 {ISIS_CIRCLEVEL_MINLSPRETRANSINT
, UNSIGNED32
, RONLY
,
517 isis_snmp_find_circ_level
},
518 {ISIS_CIRCLEVEL_CSNPINTERVAL
, UNSIGNED32
, RONLY
,
519 isis_snmp_find_circ_level
},
520 {ISIS_CIRCLEVEL_PARTSNPINTERVAL
, UNSIGNED32
, RONLY
,
521 isis_snmp_find_circ_level
},
522 {ISIS_CIRC_ADJCHANGES
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
523 {ISIS_CIRC_NUMADJ
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_counter
},
524 {ISIS_CIRC_INITFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
525 {ISIS_CIRC_REJADJS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
526 {ISIS_CIRC_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
527 isis_snmp_find_circ_counter
},
528 {ISIS_CIRC_MAXAREAADDRMISMATCHES
, COUNTER32
, RONLY
,
529 isis_snmp_find_circ_counter
},
530 {ISIS_CIRC_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
531 isis_snmp_find_circ_counter
},
532 {ISIS_CIRC_AUTHFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
533 {ISIS_CIRC_LANDESISCHANGES
, COUNTER32
, RONLY
,
534 isis_snmp_find_circ_counter
},
535 {ISIS_ISADJ_STATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
536 {ISIS_ISADJ_3WAYSTATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
537 {ISIS_ISADJ_NEIGHSNPAADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj
},
538 {ISIS_ISADJ_NEIGHSYSTYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
539 {ISIS_ISADJ_NEIGHSYSID
, STRING
, RONLY
, isis_snmp_find_isadj
},
540 {ISIS_ISADJ_NBREXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
541 {ISIS_ISADJ_USAGE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
542 {ISIS_ISADJ_HOLDTIMER
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
543 {ISIS_ISADJ_NEIGHPRIORITY
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
544 {ISIS_ISADJ_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_isadj
},
545 {ISIS_ISADJAREA_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_area
},
546 {ISIS_ISADJIPADDR_TYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj_ipaddr
},
547 {ISIS_ISADJIPADDR_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_ipaddr
},
548 {ISIS_ISADJPROTSUPP_PROTOCOL
, INTEGER
, RONLY
,
549 isis_snmp_find_isadj_prot_supp
},
552 static const size_t isis_var_count
= array_size(isis_var_arr
);
554 /* Minimal set of hard-coded data */
555 #define ISIS_VERSION (1)
557 /* If sys-id is not set use this value */
558 static uint8_t isis_null_sysid
[ISIS_SYS_ID_LEN
];
561 #define ISIS_SNMP_OSI_ADDR_LEN_MAX (20)
564 * The implementation has a fixed max-path splits value
565 * of 64 (see ISIS_MAX_PATH_SPLITS), the max mib value
568 * FIXME(aromanov): should we return 32 or 64?
570 #define ISIS_SNMP_MAX_PATH_SPLITS (32)
572 #define ISIS_SNMP_ADMIN_STATE_ON (1)
574 #define ISIS_SNMP_ROW_STATUS_ACTIVE (1)
576 #define ISIS_SNMP_LEVEL_STATE_OFF (1)
577 #define ISIS_SNMP_LEVEL_STATE_ON (2)
578 #define ISIS_SNMP_LEVEL_STATE_WAITING (3)
579 #define ISIS_SNMP_LEVEL_STATE_OVERLOADED (4)
581 #define ISIS_SNMP_TRUTH_VALUE_TRUE (1)
582 #define ISIS_SNMP_TRUTH_VALUE_FALSE (2)
584 #define ISIS_SNMP_METRIC_STYLE_NARROW (1)
585 #define ISIS_SNMP_METRIC_STYLE_WIDE (2)
586 #define ISIS_SNMP_METRIC_STYLE_BOTH (3)
588 #define ISIS_SNMP_MESH_GROUP_INACTIVE (1)
590 #define ISIS_SNMP_ADJ_STATE_DOWN (1)
591 #define ISIS_SNMP_ADJ_STATE_INITIALIZING (2)
592 #define ISIS_SNMP_ADJ_STATE_UP (3)
593 #define ISIS_SNMP_ADJ_STATE_FAILED (4)
595 static inline uint32_t isis_snmp_adj_state(enum isis_adj_state state
)
598 case ISIS_ADJ_UNKNOWN
:
599 return ISIS_SNMP_ADJ_STATE_DOWN
;
600 case ISIS_ADJ_INITIALIZING
:
601 return ISIS_SNMP_ADJ_STATE_INITIALIZING
;
603 return ISIS_SNMP_ADJ_STATE_UP
;
605 return ISIS_SNMP_ADJ_STATE_FAILED
;
608 return 0; /* not reached */
611 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1 (1)
612 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2 (2)
613 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2 (3)
614 #define ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN (4)
616 static inline uint32_t isis_snmp_adj_neightype(enum isis_system_type type
)
619 case ISIS_SYSTYPE_UNKNOWN
:
620 case ISIS_SYSTYPE_ES
:
621 return ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN
;
622 case ISIS_SYSTYPE_IS
:
623 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2
;
624 case ISIS_SYSTYPE_L1_IS
:
625 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1
;
626 case ISIS_SYSTYPE_L2_IS
:
627 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2
;
630 return 0; /* not reached */
633 #define ISIS_SNMP_INET_TYPE_V4 (1)
634 #define ISIS_SNMP_INET_TYPE_V6 (2)
636 #define ISIS_SNMP_P2P_CIRCUIT (3)
638 /* Protocols supported value */
639 static uint8_t isis_snmp_protocols_supported
= 0x7; /* All: iso, ipv4, ipv6 */
641 #define SNMP_CIRCUITS_MAX (512)
643 static struct isis_circuit
*snmp_circuits
[SNMP_CIRCUITS_MAX
];
644 static uint32_t snmp_circuit_id_last
;
646 static int isis_circuit_snmp_id_gen(struct isis_circuit
*circuit
)
651 id
= snmp_circuit_id_last
;
654 /* find next unused entry */
655 for (i
= 0; i
< SNMP_CIRCUITS_MAX
; i
++) {
656 if (id
>= SNMP_CIRCUITS_MAX
) {
664 if (snmp_circuits
[id
] == NULL
)
670 if (i
== SNMP_CIRCUITS_MAX
) {
671 zlog_warn("Could not allocate a smmp-circuit-id");
675 snmp_circuits
[id
] = circuit
;
676 snmp_circuit_id_last
= id
;
677 circuit
->snmp_id
= id
;
682 static int isis_circuit_snmp_id_free(struct isis_circuit
*circuit
)
684 snmp_circuits
[circuit
->snmp_id
] = NULL
;
685 circuit
->snmp_id
= 0;
690 * Convenience function to move to the next circuit,
692 static struct isis_circuit
*isis_snmp_circuit_next(struct isis_circuit
*circuit
)
700 start
= circuit
->snmp_id
+ 1;
702 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
703 circuit
= snmp_circuits
[off
];
713 * Convenience function to get the first matching level
715 static int isis_snmp_circuit_get_level_lo(struct isis_circuit
*circuit
)
717 if (circuit
->is_type
== IS_LEVEL_2
)
723 /* Check level match */
724 static int isis_snmp_get_level_match(int is_type
, int level
)
726 if (is_type
!= IS_LEVEL_1
&& is_type
!= IS_LEVEL_2
727 && is_type
!= IS_LEVEL_1_AND_2
)
730 if (level
!= IS_LEVEL_1
&& level
!= IS_LEVEL_2
)
734 if (is_type
== IS_LEVEL_1
) {
735 if (level
== IS_LEVEL_1
)
741 if (is_type
== IS_LEVEL_2
) {
742 if (level
== IS_LEVEL_2
)
751 * Helper function to convert oid index representing
752 * octet-string index (e.g. isis-sys-id) to byte string
753 * representing the same index.
755 * Also we do not fail if idx is longer than max_len,
756 * so we can use the same function to check compound
759 static int isis_snmp_conv_exact(uint8_t *buf
, size_t max_len
, size_t *out_len
,
760 const oid
*idx
, size_t idx_len
)
765 /* Oid representation: length followed by bytes */
766 if (idx
== NULL
|| idx_len
== 0)
774 if (idx_len
< len
+ 1)
777 for (off
= 0; off
< len
; off
++) {
778 if (idx
[off
+ 1] > 0xff)
781 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
789 static int isis_snmp_conv_next(uint8_t *buf
, size_t max_len
, size_t *out_len
,
790 int *try_exact
, const oid
*idx
, size_t idx_len
)
796 if (idx
== NULL
|| idx_len
== 0) {
809 if ((idx_len
- 1) < cmp_len
)
810 cmp_len
= idx_len
- 1;
812 for (off
= 0; off
< cmp_len
; off
++) {
813 if (idx
[off
+ 1] > 0xff) {
814 memset(buf
+ off
, 0xff, len
- off
);
820 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
824 memset(buf
+ cmp_len
, 0, len
- cmp_len
);
827 *try_exact
= cmp_len
< len
? 1 : 0;
832 * Helper functions to find area address from snmp index
834 static int isis_snmp_area_addr_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
835 struct isis_area
**ret_area
,
836 struct iso_address
**ret_addr
)
838 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
840 struct isis_area
*area
= NULL
;
841 struct iso_address
*addr
= NULL
;
842 struct listnode
*addr_node
;
843 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
848 if (list_isempty(isis
->area_list
)) {
849 /* Area is not configured yet */
853 area
= listgetdata(listhead(isis
->area_list
));
855 int res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
856 oid_idx
, oid_idx_len
);
859 if (!res
|| addr_len
== 0 || oid_idx_len
!= (addr_len
+ 1)) {
860 /* Bad conversion, empty address or extra oids at the end */
864 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
865 if (addr
->addr_len
!= addr_len
)
868 if (memcmp(addr
->area_addr
, cmp_buf
, addr_len
) == 0) {
881 static int isis_snmp_area_addr_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
882 struct isis_area
**ret_area
,
883 struct iso_address
**ret_addr
)
885 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
888 struct isis_area
*found_area
= NULL
;
889 struct isis_area
*area
= NULL
;
890 struct iso_address
*found_addr
= NULL
;
891 struct iso_address
*addr
= NULL
;
892 struct listnode
*addr_node
;
893 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
898 if (list_isempty(isis
->area_list
)) {
899 /* Area is not configured yet */
903 area
= listgetdata(listhead(isis
->area_list
));
905 int res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
906 &try_exact
, oid_idx
, oid_idx_len
);
911 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
912 if (addr
->addr_len
< addr_len
)
915 if (addr
->addr_len
== addr_len
) {
919 res
= memcmp(addr
->area_addr
, cmp_buf
, addr_len
);
924 if (res
== 0 && addr
->addr_len
== addr_len
) {
927 * This is the best match no point
938 if (found_addr
== NULL
|| addr
->addr_len
< found_addr
->addr_len
939 || (addr
->addr_len
== found_addr
->addr_len
940 && memcmp(addr
->area_addr
, found_addr
->area_addr
,
948 if (found_area
== NULL
)
952 *ret_area
= found_area
;
955 *ret_addr
= found_addr
;
961 * Helper functions to find circuit from
964 static int isis_snmp_circuit_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
965 struct isis_circuit
**ret_circuit
)
967 struct isis_circuit
*circuit
;
969 if (oid_idx
== NULL
|| oid_idx_len
< 1
970 || oid_idx
[0] > SNMP_CIRCUITS_MAX
)
973 circuit
= snmp_circuits
[oid_idx
[0]];
977 if (ret_circuit
!= NULL
)
978 *ret_circuit
= circuit
;
983 static int isis_snmp_circuit_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
984 struct isis_circuit
**ret_circuit
)
988 struct isis_circuit
*circuit
;
992 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
993 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
999 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; ++off
) {
1000 circuit
= snmp_circuits
[off
];
1002 if (circuit
!= NULL
&& off
> start
) {
1003 if (ret_circuit
!= NULL
)
1004 *ret_circuit
= circuit
;
1014 * Helper functions to find circuit level
1015 * combination from snmp index
1017 static int isis_snmp_circuit_level_lookup_exact(
1018 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
1019 struct isis_circuit
**ret_circuit
, int *ret_level
)
1023 struct isis_circuit
*circuit
;
1025 /* Minor optimization: check level first */
1026 if (oid_idx
== NULL
|| oid_idx_len
< 2)
1029 if (oid_idx
[1] < IS_LEVEL_1
|| oid_idx
[1] > IS_LEVEL_2
)
1032 level
= (int)oid_idx
[1];
1034 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1039 if (check_match
&& !isis_snmp_get_level_match(circuit
->is_type
, level
))
1042 if (ret_circuit
!= NULL
)
1043 *ret_circuit
= circuit
;
1045 if (ret_level
!= NULL
)
1051 static int isis_snmp_circuit_level_lookup_next(
1052 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
1053 struct isis_circuit
**ret_circuit
, int *ret_level
)
1057 struct isis_circuit
*circuit
= NULL
;
1062 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
1063 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
1069 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
1070 circuit
= snmp_circuits
[off
];
1072 if (circuit
== NULL
)
1075 if (off
> start
|| oid_idx_len
< 2) {
1076 /* Found and can use level 1 */
1081 assert(oid_idx
!= NULL
);
1083 /* We have to check level specified by index */
1084 if (oid_idx
[1] < IS_LEVEL_1
) {
1089 if (oid_idx
[1] < IS_LEVEL_2
) {
1098 if (circuit
== NULL
)
1102 && !isis_snmp_get_level_match(circuit
->is_type
, level
)) {
1103 if (level
== IS_LEVEL_1
) {
1105 * We can simply advance level because
1106 * at least one level should match
1110 /* We have to move to the next circuit */
1111 circuit
= isis_snmp_circuit_next(circuit
);
1112 if (circuit
== NULL
)
1115 level
= isis_snmp_circuit_get_level_lo(circuit
);
1119 if (ret_circuit
!= NULL
)
1120 *ret_circuit
= circuit
;
1122 if (ret_level
!= NULL
)
1129 * Helper functions to find adjacency
1132 * We have 4 tables related to adjacency
1133 * looking up adjacency is quite expensive
1134 * in case of bcast interfaces.
1136 * It is pain to have 4 very similar functions
1137 * hence we pass in and out additional data
1138 * we are looking for.
1140 * Note: we use data-len value to distinguish
1141 * between ipv4 and ipv6 addresses
1143 #define ISIS_SNMP_ADJ_DATA_NONE (1)
1144 #define ISIS_SNMP_ADJ_DATA_AREA_ADDR (2)
1145 #define ISIS_SNMP_ADJ_DATA_IP_ADDR (3)
1146 #define ISIS_SNMP_ADJ_DATA_PROTO (4)
1149 * Helper function to process data associated
1152 static int isis_snmp_adj_helper(struct isis_adjacency
*adj
, int data_id
,
1153 oid data_off
, uint8_t **ret_data
,
1154 size_t *ret_data_len
)
1156 uint8_t *data
= NULL
;
1157 size_t data_len
= 0;
1160 case ISIS_SNMP_ADJ_DATA_NONE
:
1163 case ISIS_SNMP_ADJ_DATA_AREA_ADDR
:
1164 if (data_off
>= adj
->area_address_count
)
1167 data
= adj
->area_addresses
[data_off
].area_addr
;
1168 data_len
= adj
->area_addresses
[data_off
].addr_len
;
1171 case ISIS_SNMP_ADJ_DATA_IP_ADDR
:
1172 if (data_off
>= (adj
->ipv4_address_count
+ adj
->ll_ipv6_count
))
1175 if (data_off
>= adj
->ipv4_address_count
) {
1176 data
= (uint8_t *)&adj
->ll_ipv6_addrs
1177 [data_off
- adj
->ipv4_address_count
];
1178 data_len
= sizeof(adj
->ll_ipv6_addrs
[0]);
1180 data
= (uint8_t *)&adj
->ipv4_addresses
[data_off
];
1181 data_len
= sizeof(adj
->ipv4_addresses
[0]);
1187 case ISIS_SNMP_ADJ_DATA_PROTO
:
1188 if (data_off
>= adj
->nlpids
.count
)
1191 data
= &adj
->nlpids
.nlpids
[data_off
];
1192 data_len
= sizeof(adj
->nlpids
.nlpids
[0]);
1200 if (ret_data
!= NULL
)
1203 if (ret_data_len
!= NULL
)
1204 *ret_data_len
= data_len
;
1209 static int isis_snmp_adj_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
1211 struct isis_adjacency
**ret_adj
,
1212 oid
*ret_data_idx
, uint8_t **ret_data
,
1213 size_t *ret_data_len
)
1216 struct listnode
*node
;
1217 struct isis_circuit
*circuit
;
1218 struct isis_adjacency
*adj
;
1219 struct isis_adjacency
*tmp_adj
;
1225 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1230 if (oid_idx
== NULL
|| oid_idx_len
< 2
1231 || (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
&& oid_idx_len
< 3))
1234 adj_idx
= oid_idx
[1];
1236 if (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
) {
1237 if (oid_idx
[2] == 0)
1240 data_off
= oid_idx
[2] - 1;
1243 * Data-off is not used if data-id is none
1244 * but we set it just for consistency
1253 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
, tmp_adj
)) {
1254 if (tmp_adj
->snmp_idx
> adj_idx
) {
1256 * Adjacencies are ordered in the list
1257 * no point to look further
1262 if (tmp_adj
->snmp_idx
== adj_idx
) {
1263 res
= isis_snmp_adj_helper(tmp_adj
, data_id
, data_off
,
1275 if (ret_adj
!= NULL
)
1278 if (ret_data_idx
!= NULL
)
1279 *ret_data_idx
= data_off
+ 1;
1285 *ret_data_len
= data_len
;
1290 static int isis_snmp_adj_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
1292 struct isis_adjacency
**ret_adj
,
1293 oid
*ret_data_idx
, uint8_t **ret_data
,
1294 size_t *ret_data_len
)
1296 struct listnode
*node
;
1297 struct isis_circuit
*circuit
;
1298 struct isis_adjacency
*adj
;
1299 struct isis_adjacency
*tmp_adj
;
1311 * Note: we rely on the fact that data indexes are consequtive
1315 if (oid_idx
== 0 || oid_idx_len
== 0) {
1319 } else if (oid_idx_len
== 1) {
1320 circ_idx
= oid_idx
[0];
1323 } else if (oid_idx_len
== 2) {
1324 circ_idx
= oid_idx
[0];
1325 adj_idx
= oid_idx
[1];
1328 circ_idx
= oid_idx
[0];
1329 adj_idx
= oid_idx
[1];
1331 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1334 data_idx
= oid_idx
[2];
1337 if (!isis_snmp_circuit_lookup_exact(&circ_idx
, 1, &circuit
)
1338 && !isis_snmp_circuit_lookup_next(&circ_idx
, 1, &circuit
))
1342 if (circuit
->snmp_id
!= circ_idx
) {
1343 /* Match is not exact */
1350 * Note: the simple loop below will work in all cases
1352 while (circuit
!= NULL
) {
1353 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
,
1355 if (tmp_adj
->snmp_idx
< adj_idx
)
1358 if (tmp_adj
->snmp_idx
== adj_idx
1359 && data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1362 if (adj_idx
!= 0 && tmp_adj
->snmp_idx
> adj_idx
)
1365 if (isis_snmp_adj_helper(tmp_adj
, data_id
, data_idx
,
1366 &data
, &data_len
)) {
1375 circuit
= isis_snmp_circuit_next(circuit
);
1384 if (ret_adj
!= NULL
)
1387 if (ret_data_idx
!= 0) {
1388 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1390 * Value does not matter but let us set
1391 * it to zero for consistency
1395 *ret_data_idx
= data_idx
+ 1;
1401 if (ret_data_len
!= 0)
1402 *ret_data_len
= data_len
;
1407 static uint8_t *isis_snmp_find_sys_object(struct variable
*v
, oid
*name
,
1408 size_t *length
, int exact
,
1410 WriteMethod
**write_method
)
1412 struct isis_area
*area
= NULL
;
1413 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1418 if (!list_isempty(isis
->area_list
))
1419 area
= listgetdata(listhead(isis
->area_list
));
1421 /* Check whether the instance identifier is valid */
1422 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
1427 case ISIS_SYS_VERSION
:
1428 return SNMP_INTEGER(ISIS_VERSION
);
1430 case ISIS_SYS_LEVELTYPE
:
1432 * If we do not have areas use 1&2 otherwise use settings
1433 * from the first area in the list
1436 return SNMP_INTEGER(IS_LEVEL_1_AND_2
);
1438 return SNMP_INTEGER(area
->is_type
);
1441 if (!isis
->sysid_set
) {
1442 *var_len
= ISIS_SYS_ID_LEN
;
1443 return isis_null_sysid
;
1446 *var_len
= ISIS_SYS_ID_LEN
;
1449 case ISIS_SYS_MAXPATHSPLITS
:
1450 return SNMP_INTEGER(ISIS_SNMP_MAX_PATH_SPLITS
);
1452 case ISIS_SYS_MAXLSPGENINT
:
1453 return SNMP_INTEGER(DEFAULT_MAX_LSP_GEN_INTERVAL
);
1455 case ISIS_SYS_POLLESHELLORATE
:
1456 return SNMP_INTEGER(DEFAULT_HELLO_INTERVAL
);
1458 case ISIS_SYS_WAITTIME
:
1459 /* Note: it seems that we have same fixed delay time */
1460 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1462 case ISIS_SYS_ADMINSTATE
:
1463 /* If daemon is running it admin state is on */
1464 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
1467 case ISIS_SYS_L2TOL1LEAKING
:
1468 /* We do not allow l2-to-l1 leaking */
1469 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1471 case ISIS_SYS_MAXAGE
:
1472 return SNMP_INTEGER(MAX_AGE
);
1474 case ISIS_SYS_RECEIVELSPBUFFERSIZE
:
1476 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1478 return SNMP_INTEGER(area
->lsp_mtu
);
1480 case ISIS_SYS_PROTSUPPORTED
:
1482 return &isis_snmp_protocols_supported
;
1484 case ISIS_SYS_NOTIFICATIONENABLE
:
1485 if (isis
->snmp_notifications
)
1486 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1488 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1498 static uint8_t *isis_snmp_find_man_area(struct variable
*v
, oid
*name
,
1499 size_t *length
, int exact
,
1501 WriteMethod
**write_method
)
1504 struct iso_address
*area_addr
= NULL
;
1509 *write_method
= NULL
;
1511 if (*length
<= v
->namelen
) {
1514 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1518 oid_idx
= name
+ v
->namelen
;
1519 oid_idx_len
= *length
- v
->namelen
;
1523 res
= isis_snmp_area_addr_lookup_exact(oid_idx
, oid_idx_len
,
1530 res
= isis_snmp_area_addr_lookup_next(oid_idx
, oid_idx_len
,
1536 /* Copy the name out */
1537 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1540 name
[v
->namelen
] = area_addr
->addr_len
;
1542 for (off
= 0; off
< area_addr
->addr_len
; off
++)
1543 name
[v
->namelen
+ 1 + off
] = area_addr
->area_addr
[off
];
1545 *length
= v
->namelen
+ 1 + area_addr
->addr_len
;
1549 case ISIS_MANAREA_ADDREXISTSTATE
:
1550 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
1559 static uint8_t *isis_snmp_find_area_addr(struct variable
*v
, oid
*name
,
1560 size_t *length
, int exact
,
1562 WriteMethod
**write_method
)
1565 * Area addresses in sense of addresses reported by L1 lsps
1566 * are not supported yet.
1575 *write_method
= NULL
;
1580 static uint8_t *isis_snmp_find_summ_addr(struct variable
*v
, oid
*name
,
1581 size_t *length
, int exact
,
1583 WriteMethod
**write_method
)
1586 * So far there is no way to set summary table values through cli
1587 * and snmp operations are read-only, hence there are no entries
1594 *write_method
= NULL
;
1599 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*v
, oid
*name
,
1600 size_t *length
, int exact
,
1602 WriteMethod
**write_method
)
1605 * It is not clear at the point whether redist code in isis is actually
1606 * used for now we will consider that entries are not present
1613 *write_method
= NULL
;
1618 static uint8_t *isis_snmp_find_router(struct variable
*v
, oid
*name
,
1619 size_t *length
, int exact
,
1621 WriteMethod
**write_method
)
1623 uint8_t cmp_buf
[ISIS_SYS_ID_LEN
];
1628 struct isis_dynhn
*dyn
= NULL
;
1632 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1637 *write_method
= NULL
;
1639 if (*length
<= v
->namelen
) {
1642 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1646 oid_idx
= name
+ v
->namelen
;
1647 oid_idx_len
= *length
- v
->namelen
;
1651 res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1652 oid_idx
, oid_idx_len
);
1654 if (!res
|| cmp_len
!= ISIS_SYS_ID_LEN
1655 || oid_idx_len
!= (cmp_len
+ 2))
1657 * Bad conversion, or bad length,
1658 * or extra oids at the end
1662 if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] < IS_LEVEL_1
1663 || oid_idx
[ISIS_SYS_ID_LEN
+ 1] > IS_LEVEL_2
)
1664 /* Level part of the index is out of range */
1667 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1669 dyn
= dynhn_find_by_id(isis
, cmp_buf
);
1671 if (dyn
== NULL
|| dyn
->level
!= cmp_level
)
1675 case ISIS_ROUTER_HOSTNAME
:
1676 *var_len
= strlen(dyn
->hostname
);
1677 return (uint8_t *)dyn
->hostname
;
1679 case ISIS_ROUTER_ID
:
1680 /* It seems that we do no know router-id in lsps */
1681 return SNMP_INTEGER(0);
1690 res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1691 &try_exact
, oid_idx
, oid_idx_len
);
1695 /* Bad conversion */
1698 if (cmp_len
!= ISIS_SYS_ID_LEN
) {
1699 /* We do not have valid index oids */
1700 memset(cmp_buf
, 0, sizeof(cmp_buf
));
1702 } else if (try_exact
)
1704 * We have no valid level index.
1705 * Let start from non-existing level 0 and
1706 * hence not need to do exact match
1709 else if (oid_idx_len
< (ISIS_SYS_ID_LEN
+ 2))
1711 else if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] <= IS_LEVEL_2
)
1712 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1715 * Any value greater than 2 will have the same result
1716 * but we can have integer overflows, hence 3 is a reasonable
1719 cmp_level
= (int)(IS_LEVEL_2
+ 1);
1721 dyn
= dynhn_snmp_next(isis
, cmp_buf
, cmp_level
);
1726 /* Copy the name out */
1727 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1730 name
[v
->namelen
] = ISIS_SYS_ID_LEN
;
1732 for (off
= 0; off
< ISIS_SYS_ID_LEN
; off
++)
1733 name
[v
->namelen
+ 1 + off
] = dyn
->id
[off
];
1735 name
[v
->namelen
+ 1 + ISIS_SYS_ID_LEN
] = (oid
)dyn
->level
;
1738 *length
= v
->namelen
+ 1 + ISIS_SYS_ID_LEN
+ 1;
1741 case ISIS_ROUTER_HOSTNAME
:
1742 *var_len
= strlen(dyn
->hostname
);
1743 return (uint8_t *)dyn
->hostname
;
1745 case ISIS_ROUTER_ID
:
1746 /* It seems that we do no know router-id in lsps */
1747 return SNMP_INTEGER(0);
1756 static uint8_t *isis_snmp_find_sys_level(struct variable
*v
, oid
*name
,
1757 size_t *length
, int exact
,
1759 WriteMethod
**write_method
)
1765 struct isis_area
*area
= NULL
;
1766 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1771 *write_method
= NULL
;
1773 if (*length
<= v
->namelen
) {
1776 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1780 oid_idx
= name
+ v
->namelen
;
1781 oid_idx_len
= *length
- v
->namelen
;
1785 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1788 if (oid_idx
[0] == IS_LEVEL_1
)
1790 else if (oid_idx
[0] == IS_LEVEL_2
)
1796 if (oid_idx
== NULL
)
1798 else if (oid_idx_len
== 0)
1800 else if (oid_idx
[0] < IS_LEVEL_1
)
1802 else if (oid_idx
[0] < IS_LEVEL_2
)
1807 /* Copy the name out */
1808 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1811 name
[v
->namelen
] = level
;
1814 *length
= v
->namelen
+ 1;
1819 if (!list_isempty(isis
->area_list
))
1820 area
= listgetdata(listhead(isis
->area_list
));
1825 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1828 case ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
:
1830 return SNMP_INTEGER(area
->lsp_mtu
);
1832 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1834 case ISIS_SYSLEVEL_MINLSPGENINT
:
1836 return SNMP_INTEGER(area
->lsp_gen_interval
[level
- 1]);
1838 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1840 case ISIS_SYSLEVEL_STATE
:
1842 if (area
->overload_bit
)
1843 return SNMP_INTEGER(
1844 ISIS_SNMP_LEVEL_STATE_OVERLOADED
);
1846 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_ON
);
1848 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_OFF
);
1850 case ISIS_SYSLEVEL_SETOVERLOAD
:
1851 if (level_match
&& area
->overload_bit
)
1852 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1854 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1856 case ISIS_SYSLEVEL_SETOVERLOADUNTIL
:
1857 /* We do not have automatic cleanup of overload bit */
1858 return SNMP_INTEGER(0);
1860 case ISIS_SYSLEVEL_METRICSTYLE
:
1862 if (area
->newmetric
&& area
->oldmetric
)
1863 return SNMP_INTEGER(
1864 ISIS_SNMP_METRIC_STYLE_BOTH
);
1866 if (area
->newmetric
)
1867 return SNMP_INTEGER(
1868 ISIS_SNMP_METRIC_STYLE_WIDE
);
1870 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1872 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1874 case ISIS_SYSLEVEL_SPFCONSIDERS
:
1875 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_BOTH
);
1877 case ISIS_SYSLEVEL_TEENABLED
:
1878 if (level_match
&& IS_MPLS_TE(area
->mta
))
1879 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1881 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1890 static uint8_t *isis_snmp_find_system_counter(struct variable
*v
, oid
*name
,
1891 size_t *length
, int exact
,
1893 WriteMethod
**write_method
)
1899 struct isis_area
*area
= NULL
;
1901 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1906 *write_method
= NULL
;
1908 if (*length
<= v
->namelen
) {
1911 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1915 oid_idx
= name
+ v
->namelen
;
1916 oid_idx_len
= *length
- v
->namelen
;
1920 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1923 if (oid_idx
[0] == IS_LEVEL_1
)
1925 else if (oid_idx
[0] == IS_LEVEL_2
)
1931 if (oid_idx
== NULL
)
1933 else if (oid_idx_len
== 0)
1935 else if (oid_idx
[0] < IS_LEVEL_1
)
1937 else if (oid_idx
[0] < IS_LEVEL_2
)
1942 /* Copy the name out */
1943 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1946 name
[v
->namelen
] = level
;
1949 *length
= v
->namelen
+ 1;
1954 if (!list_isempty(isis
->area_list
))
1955 area
= listgetdata(listhead(isis
->area_list
));
1960 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1963 /* If level does not match all counters are zeros */
1964 return SNMP_INTEGER(0);
1967 case ISIS_SYSSTAT_CORRLSPS
:
1971 case ISIS_SYSSTAT_AUTHTYPEFAILS
:
1972 val
= (uint32_t)area
->auth_type_failures
[level
- 1];
1975 case ISIS_SYSSTAT_AUTHFAILS
:
1976 val
= (uint32_t)area
->auth_failures
[level
- 1];
1979 case ISIS_SYSSTAT_LSPDBASEOLOADS
:
1980 val
= area
->overload_counter
;
1983 case ISIS_SYSSTAT_MANADDRDROPFROMAREAS
:
1984 /* We do not support manual addresses */
1988 case ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
:
1989 val
= area
->lsp_exceeded_max_counter
;
1992 case ISIS_SYSSTAT_SEQNUMSKIPS
:
1993 val
= area
->lsp_seqno_skipped_counter
;
1996 case ISIS_SYSSTAT_OWNLSPPURGES
:
1997 if (!area
->purge_originator
)
2000 val
= area
->lsp_purge_count
[level
- 1];
2003 case ISIS_SYSSTAT_IDFIELDLENMISMATCHES
:
2004 val
= (uint32_t)area
->id_len_mismatches
[level
- 1];
2007 case ISIS_SYSSTAT_PARTCHANGES
:
2012 case ISIS_SYSSTAT_SPFRUNS
:
2013 val
= (uint32_t)area
->spf_run_count
[level
- 1];
2016 case ISIS_SYSSTAT_LSPERRORS
:
2017 val
= (uint32_t)area
->lsp_error_counter
[level
- 1];
2024 return SNMP_INTEGER(val
);
2027 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*v
, oid
*name
,
2028 size_t *length
, int exact
,
2030 WriteMethod
**write_method
)
2032 /* Check whether the instance identifier is valid */
2033 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
2038 case ISIS_NEXTCIRC_INDEX
:
2040 * We do not support circuit creation through snmp
2042 return SNMP_INTEGER(0);
2051 static uint8_t *isis_snmp_find_circ(struct variable
*v
, oid
*name
,
2052 size_t *length
, int exact
, size_t *var_len
,
2053 WriteMethod
**write_method
)
2055 /* Index is circuit-id: 1-255 */
2058 struct isis_circuit
*circuit
;
2060 uint32_t delta_ticks
;
2064 *write_method
= NULL
;
2066 if (*length
<= v
->namelen
) {
2069 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2073 oid_idx
= name
+ v
->namelen
;
2074 oid_idx_len
= *length
- v
->namelen
;
2077 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
,
2080 if (!res
|| oid_idx_len
!= 1)
2084 res
= isis_snmp_circuit_lookup_next(oid_idx
, oid_idx_len
,
2090 /* Copy the name out */
2091 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2094 name
[v
->namelen
] = circuit
->snmp_id
;
2097 *length
= v
->namelen
+ 1;
2101 case ISIS_CIRC_IFINDEX
:
2102 if (circuit
->interface
== NULL
)
2103 return SNMP_INTEGER(0);
2105 return SNMP_INTEGER(circuit
->interface
->ifindex
);
2107 case ISIS_CIRC_ADMINSTATE
:
2108 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
2110 case ISIS_CIRC_EXISTSTATE
:
2111 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
2113 case ISIS_CIRC_TYPE
:
2115 * Note: values do not match 100%:
2117 * 1. From isis_circuit.h:
2118 * CIRCUIT_T_UNKNOWN 0
2119 * CIRCUIT_T_BROADCAST 1
2121 * CIRCUIT_T_LOOPBACK 3
2130 return SNMP_INTEGER(circuit
->circ_type
);
2132 case ISIS_CIRC_EXTDOMAIN
:
2133 if (circuit
->ext_domain
)
2134 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2136 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2138 case ISIS_CIRC_LEVELTYPE
:
2139 return SNMP_INTEGER(circuit
->is_type
);
2141 case ISIS_CIRC_PASSIVECIRCUIT
:
2142 if (circuit
->is_passive
)
2143 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2145 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2147 case ISIS_CIRC_MESHGROUPENABLED
:
2149 return SNMP_INTEGER(ISIS_SNMP_MESH_GROUP_INACTIVE
);
2151 case ISIS_CIRC_MESHGROUP
:
2153 return SNMP_INTEGER(0);
2155 case ISIS_CIRC_SMALLHELLOS
:
2157 * return false if lan hellos must be padded
2159 if (circuit
->pad_hellos
== ISIS_HELLO_PADDING_ALWAYS
||
2160 (circuit
->pad_hellos
==
2161 ISIS_HELLO_PADDING_DURING_ADJACENCY_FORMATION
&&
2162 circuit
->upadjcount
[0] + circuit
->upadjcount
[1] == 0))
2163 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2165 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2167 case ISIS_CIRC_LASTUPTIME
:
2168 if (circuit
->last_uptime
== 0)
2169 return SNMP_INTEGER(0);
2171 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2172 now_time
= time(NULL
);
2174 if (circuit
->last_uptime
>= now_time
)
2175 return SNMP_INTEGER(up_ticks
);
2177 delta_ticks
= (now_time
- circuit
->last_uptime
) * 10;
2179 if (up_ticks
< delta_ticks
)
2180 return SNMP_INTEGER(up_ticks
);
2182 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2184 case ISIS_CIRC_3WAYENABLED
:
2186 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2188 case ISIS_CIRC_EXTENDEDCIRCID
:
2189 /* Used for 3-way hand shake only */
2190 return SNMP_INTEGER(0);
2199 static uint8_t *isis_snmp_find_circ_level(struct variable
*v
, oid
*name
,
2200 size_t *length
, int exact
,
2202 WriteMethod
**write_method
)
2204 static uint8_t circuit_id_val
[ISIS_SYS_ID_LEN
+ 1];
2205 /* Index is circuit-id: 1-255 + level: 1-2 */
2209 struct isis_circuit
*circuit
;
2211 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2216 *write_method
= NULL
;
2218 if (*length
<= v
->namelen
) {
2221 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2225 oid_idx
= name
+ v
->namelen
;
2226 oid_idx_len
= *length
- v
->namelen
;
2229 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2230 1, &circuit
, &level
);
2232 if (!res
|| oid_idx_len
!= 2)
2236 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2237 1, &circuit
, &level
);
2242 /* Copy the name out */
2243 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2246 name
[v
->namelen
] = circuit
->snmp_id
;
2247 name
[v
->namelen
+ 1] = level
;
2250 *length
= v
->namelen
+ 2;
2254 case ISIS_CIRCLEVEL_METRIC
:
2255 return SNMP_INTEGER(circuit
->metric
[level
- 1]);
2257 case ISIS_CIRCLEVEL_WIDEMETRIC
:
2258 if (circuit
->area
== NULL
|| !circuit
->area
->newmetric
) {
2259 /* What should we do if wide metric is not supported? */
2260 return SNMP_INTEGER(0);
2262 return SNMP_INTEGER(circuit
->te_metric
[level
- 1]);
2264 case ISIS_CIRCLEVEL_ISPRIORITY
:
2265 return SNMP_INTEGER(circuit
->priority
[level
- 1]);
2267 case ISIS_CIRCLEVEL_IDOCTET
:
2268 return SNMP_INTEGER(circuit
->circuit_id
);
2270 case ISIS_CIRCLEVEL_ID
:
2271 if (circuit
->circ_type
!= CIRCUIT_T_P2P
) {
2273 * Unless it is point-to-point circuit, the value is and
2274 * empty octet string
2277 return circuit_id_val
;
2280 /* !!!!!! Circuit-id is zero for p2p links */
2281 if (circuit
->u
.p2p
.neighbor
== NULL
2282 || circuit
->u
.p2p
.neighbor
->adj_state
!= ISIS_ADJ_UP
) {
2283 /* No adjacency or adjacency not fully up yet */
2284 memcpy(circuit_id_val
, isis
->sysid
, ISIS_SYS_ID_LEN
);
2285 circuit_id_val
[ISIS_SYS_ID_LEN
] = circuit
->circuit_id
;
2286 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2287 return circuit_id_val
;
2290 /* Adjacency fully-up */
2291 memcpy(circuit_id_val
, circuit
->u
.p2p
.neighbor
->sysid
,
2293 circuit_id_val
[ISIS_SYS_ID_LEN
] = 0;
2294 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2295 return circuit_id_val
;
2297 case ISIS_CIRCLEVEL_DESIS
:
2298 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
2299 || !circuit
->u
.bc
.is_dr
[level
- 1]) {
2301 * Unless it is lan circuit participating in dis process
2302 * the value is an empty octet string
2305 return circuit_id_val
;
2308 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2310 if (level
== IS_LEVEL_1
)
2311 return circuit
->u
.bc
.l1_desig_is
;
2313 return circuit
->u
.bc
.l2_desig_is
;
2315 case ISIS_CIRCLEVEL_HELLOMULTIPLIER
:
2316 return SNMP_INTEGER(circuit
->hello_multiplier
[level
- 1]);
2318 case ISIS_CIRCLEVEL_HELLOTIMER
:
2319 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2321 case ISIS_CIRCLEVEL_DRHELLOTIMER
:
2322 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2324 case ISIS_CIRCLEVEL_LSPTHROTTLE
:
2326 return SNMP_INTEGER(
2327 circuit
->area
->min_spf_interval
[level
- 1]
2330 return SNMP_INTEGER(0);
2332 case ISIS_CIRCLEVEL_MINLSPRETRANSINT
:
2334 return SNMP_INTEGER(
2335 circuit
->area
->min_spf_interval
[level
- 1]);
2337 return SNMP_INTEGER(0);
2339 case ISIS_CIRCLEVEL_CSNPINTERVAL
:
2340 return SNMP_INTEGER(circuit
->csnp_interval
[level
- 1]);
2342 case ISIS_CIRCLEVEL_PARTSNPINTERVAL
:
2343 return SNMP_INTEGER(circuit
->psnp_interval
[level
- 1]);
2352 static uint8_t *isis_snmp_find_circ_counter(struct variable
*v
, oid
*name
,
2353 size_t *length
, int exact
,
2355 WriteMethod
**write_method
)
2357 /* Index circuit-id 1-255 + level */
2361 struct isis_circuit
*circuit
;
2365 *write_method
= NULL
;
2367 if (*length
<= v
->namelen
) {
2370 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2374 oid_idx
= name
+ v
->namelen
;
2375 oid_idx_len
= *length
- v
->namelen
;
2378 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2379 1, &circuit
, &level
);
2381 if (!res
|| oid_idx_len
!= 2)
2385 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2386 1, &circuit
, &level
);
2391 /* Copy the name out */
2392 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2395 name
[v
->namelen
] = circuit
->snmp_id
;
2396 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2397 name
[v
->namelen
+ 1] = ISIS_SNMP_P2P_CIRCUIT
;
2399 name
[v
->namelen
+ 1] = level
;
2402 *length
= v
->namelen
+ 2;
2406 case ISIS_CIRC_ADJCHANGES
:
2407 val
= circuit
->adj_state_changes
;
2410 case ISIS_CIRC_NUMADJ
:
2411 if (circuit
->circ_type
== CIRCUIT_T_P2P
) {
2412 val
= circuit
->u
.p2p
.neighbor
== NULL
? 0 : 1;
2416 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
) {
2421 if (level
== IS_LEVEL_1
) {
2422 if (circuit
->u
.bc
.adjdb
[0] == NULL
)
2425 val
= listcount(circuit
->u
.bc
.adjdb
[0]);
2429 if (circuit
->u
.bc
.adjdb
[1] == NULL
)
2432 val
= listcount(circuit
->u
.bc
.adjdb
[1]);
2436 case ISIS_CIRC_INITFAILS
:
2437 val
= circuit
->init_failures
; /* counter never incremented */
2440 case ISIS_CIRC_REJADJS
:
2441 val
= circuit
->rej_adjacencies
;
2444 case ISIS_CIRC_IDFIELDLENMISMATCHES
:
2445 val
= circuit
->id_len_mismatches
;
2448 case ISIS_CIRC_MAXAREAADDRMISMATCHES
:
2449 val
= circuit
->max_area_addr_mismatches
;
2452 case ISIS_CIRC_AUTHTYPEFAILS
:
2453 val
= circuit
->auth_type_failures
;
2456 case ISIS_CIRC_AUTHFAILS
:
2457 val
= circuit
->auth_failures
;
2460 case ISIS_CIRC_LANDESISCHANGES
:
2461 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2464 val
= circuit
->desig_changes
[level
- 1];
2471 return SNMP_INTEGER(val
);
2474 static uint8_t *isis_snmp_find_isadj(struct variable
*v
, oid
*name
,
2475 size_t *length
, int exact
, size_t *var_len
,
2476 WriteMethod
**write_method
)
2478 /* Index is circuit-id: 1-255 + adj-id: 1-... */
2483 struct isis_adjacency
*adj
;
2485 uint32_t delta_ticks
;
2488 /* Ring buffer to print SNPA */
2489 #define FORMAT_BUF_COUNT 4
2490 static char snpa
[FORMAT_BUF_COUNT
][ISO_SYSID_STRLEN
];
2491 static size_t cur_buf
= 0;
2493 *write_method
= NULL
;
2495 if (*length
<= v
->namelen
) {
2498 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2502 oid_idx
= name
+ v
->namelen
;
2503 oid_idx_len
= *length
- v
->namelen
;
2506 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2507 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2510 if (!res
|| oid_idx_len
!= 2)
2514 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2515 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2520 /* Copy the name out */
2521 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2524 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2525 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2528 *length
= v
->namelen
+ 2;
2532 case ISIS_ISADJ_STATE
:
2533 return SNMP_INTEGER(isis_snmp_adj_state(adj
->adj_state
));
2535 case ISIS_ISADJ_3WAYSTATE
:
2536 return SNMP_INTEGER(adj
->threeway_state
);
2538 case ISIS_ISADJ_NEIGHSNPAADDRESS
: {
2539 cur_buf
= (cur_buf
+ 1) % FORMAT_BUF_COUNT
;
2540 snprintfrr(snpa
[cur_buf
], ISO_SYSID_STRLEN
, "%pSY", adj
->snpa
);
2541 *var_len
= strlen(snpa
[cur_buf
]);
2542 return (uint8_t *)snpa
[cur_buf
];
2545 case ISIS_ISADJ_NEIGHSYSTYPE
:
2546 return SNMP_INTEGER(isis_snmp_adj_neightype(adj
->sys_type
));
2548 case ISIS_ISADJ_NEIGHSYSID
:
2549 *var_len
= sizeof(adj
->sysid
);
2552 case ISIS_ISADJ_NBREXTENDEDCIRCID
:
2553 return SNMP_INTEGER(adj
->ext_circuit_id
!= 0 ? 1 : 0);
2555 case ISIS_ISADJ_USAGE
:
2556 /* It seems that no value conversion is required */
2557 return SNMP_INTEGER(adj
->adj_usage
);
2559 case ISIS_ISADJ_HOLDTIMER
:
2561 * It seems that we want remaining timer
2563 if (adj
->last_upd
!= 0) {
2565 if (val
< (adj
->last_upd
+ adj
->hold_time
))
2566 return SNMP_INTEGER(adj
->last_upd
2567 + adj
->hold_time
- val
);
2569 /* Not running or just expired */
2570 return SNMP_INTEGER(0);
2572 case ISIS_ISADJ_NEIGHPRIORITY
:
2573 return SNMP_INTEGER(adj
->prio
[adj
->level
- 1]);
2575 case ISIS_ISADJ_LASTUPTIME
:
2576 if (adj
->flaps
== 0)
2577 return SNMP_INTEGER(0);
2579 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2581 now_time
= time(NULL
);
2583 if (adj
->last_flap
>= now_time
)
2584 return SNMP_INTEGER(up_ticks
);
2586 delta_ticks
= (now_time
- adj
->last_flap
) * 10;
2588 if (up_ticks
< delta_ticks
)
2589 return SNMP_INTEGER(up_ticks
);
2591 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2600 static uint8_t *isis_snmp_find_isadj_area(struct variable
*v
, oid
*name
,
2601 size_t *length
, int exact
,
2603 WriteMethod
**write_method
)
2605 /* Index circuit-id: 1-255 + adj-id: 1-... */
2609 struct isis_adjacency
*adj
;
2614 *write_method
= NULL
;
2616 if (*length
<= v
->namelen
) {
2619 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2623 oid_idx
= name
+ v
->namelen
;
2624 oid_idx_len
= *length
- v
->namelen
;
2627 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2628 ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2629 &adj
, NULL
, &data
, &data_len
);
2631 if (!res
|| oid_idx_len
!= 3)
2635 res
= isis_snmp_adj_lookup_next(
2636 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2637 &adj
, &data_idx
, &data
, &data_len
);
2641 /* Copy the name out */
2642 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2645 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2646 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2647 name
[v
->namelen
+ 2] = data_idx
;
2650 *length
= v
->namelen
+ 3;
2654 case ISIS_ISADJAREA_ADDRESS
:
2655 *var_len
= data_len
;
2665 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*v
, oid
*name
,
2666 size_t *length
, int exact
,
2668 WriteMethod
**write_method
)
2670 /* Index circuit-id 1-255 + adj-id 1-... */
2674 struct isis_adjacency
*adj
;
2679 *write_method
= NULL
;
2681 if (*length
<= v
->namelen
) {
2684 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2688 oid_idx
= name
+ v
->namelen
;
2689 oid_idx_len
= *length
- v
->namelen
;
2692 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2693 ISIS_SNMP_ADJ_DATA_IP_ADDR
,
2694 &adj
, NULL
, &data
, &data_len
);
2696 if (!res
|| oid_idx_len
!= 3)
2699 res
= isis_snmp_adj_lookup_next(
2700 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_IP_ADDR
, &adj
,
2701 &data_idx
, &data
, &data_len
);
2705 /* Copy the name out */
2706 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2709 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2710 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2711 name
[v
->namelen
+ 2] = data_idx
;
2714 *length
= v
->namelen
+ 3;
2718 case ISIS_ISADJIPADDR_TYPE
:
2720 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V4
);
2722 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V6
);
2724 case ISIS_ISADJIPADDR_ADDRESS
:
2725 *var_len
= data_len
;
2735 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*v
, oid
*name
,
2736 size_t *length
, int exact
,
2738 WriteMethod
**write_method
)
2740 /* Index circuit-id 1-255 + adj-id 1-... */
2744 struct isis_adjacency
*adj
;
2749 *write_method
= NULL
;
2751 if (*length
<= v
->namelen
) {
2754 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2758 oid_idx
= name
+ v
->namelen
;
2759 oid_idx_len
= *length
- v
->namelen
;
2762 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2763 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2764 NULL
, &data
, &data_len
);
2766 if (!res
|| oid_idx_len
!= 3)
2770 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2771 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2772 &data_idx
, &data
, &data_len
);
2776 /* Copy the name out */
2777 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2780 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2781 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2782 name
[v
->namelen
+ 2] = data_idx
;
2785 *length
= v
->namelen
+ 3;
2789 case ISIS_ISADJPROTSUPP_PROTOCOL
:
2790 return SNMP_INTEGER(*data
);
2800 /* Register ISIS-MIB. */
2801 static int isis_snmp_init(struct event_loop
*tm
)
2803 struct isis_func_to_prefix
*h2f
= isis_func_to_prefix_arr
;
2806 for (size_t off
= 0; off
< isis_var_count
; off
++) {
2807 v
= &isis_var_arr
[off
];
2809 if (v
->findVar
!= h2f
->ihtp_func
) {
2812 assert(h2f
< (isis_func_to_prefix_arr
2813 + isis_func_to_prefix_count
));
2814 assert(v
->findVar
== h2f
->ihtp_func
);
2817 v
->namelen
= h2f
->ihtp_pref_len
+ 1;
2818 memcpy(v
->name
, h2f
->ihtp_pref_oid
,
2819 h2f
->ihtp_pref_len
* sizeof(oid
));
2820 v
->name
[h2f
->ihtp_pref_len
] = v
->magic
;
2825 REGISTER_MIB("mibII/isis", isis_var_arr
, variable
, isis_oid
);
2830 * ISIS notification functions: we have one function per notification
2832 static int isis_snmp_trap_throttle(oid trap_id
)
2835 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2837 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
2840 time_now
= time(NULL
);
2842 if ((isis_snmp_trap_timestamp
[trap_id
] + 5) > time_now
)
2843 /* Throttle trap rate at 1 in 5 secs */
2846 isis_snmp_trap_timestamp
[trap_id
] = time_now
;
2850 static int isis_snmp_db_overload_update(const struct isis_area
*area
)
2852 netsnmp_variable_list
*notification_vars
;
2856 if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD
))
2859 notification_vars
= NULL
;
2861 /* Put in trap value */
2862 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2863 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2864 (uint8_t *)&isis_snmp_trap_val_db_overload
,
2865 sizeof(isis_snmp_trap_val_db_overload
));
2868 val
= area
->is_type
;
2870 snmp_varlist_add_variable(
2871 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2872 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2873 (uint8_t *)&val
, sizeof(val
));
2875 /* Patch sys_level_state with proper index */
2876 off
= array_size(isis_snmp_trap_data_var_sys_level_state
) - 1;
2877 isis_snmp_trap_data_var_sys_level_state
[off
] = val
;
2880 if (area
->overload_bit
)
2881 val
= ISIS_SNMP_LEVEL_STATE_OVERLOADED
;
2883 val
= ISIS_SNMP_LEVEL_STATE_ON
;
2885 snmp_varlist_add_variable(
2886 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_state
,
2887 array_size(isis_snmp_trap_data_var_sys_level_state
), INTEGER
,
2888 (uint8_t *)&val
, sizeof(val
));
2890 send_v2trap(notification_vars
);
2891 snmp_free_varbind(notification_vars
);
2892 smux_events_update();
2896 static int isis_snmp_lsp_exceed_max_update(const struct isis_area
*area
,
2897 const uint8_t *lsp_id
)
2899 netsnmp_variable_list
*notification_vars
;
2902 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_EXCEED_MAX
))
2905 notification_vars
= NULL
;
2907 /* Put in trap value */
2908 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2909 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2910 (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max
,
2911 sizeof(isis_snmp_trap_val_lsp_exceed_max
));
2914 val
= area
->is_type
;
2916 snmp_varlist_add_variable(
2917 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2918 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2919 (uint8_t *)&val
, sizeof(val
));
2921 snmp_varlist_add_variable(
2922 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
2923 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
2924 ISIS_SYS_ID_LEN
+ 2);
2926 send_v2trap(notification_vars
);
2927 snmp_free_varbind(notification_vars
);
2928 smux_events_update();
2934 * A common function to handle popular combination of trap objects
2935 * isisNotificationSysLevelIndex,
2937 * isisNotificationCircIfIndex,
2940 static void isis_snmp_update_worker_a(const struct isis_circuit
*circuit
,
2941 oid trap_id
, const oid
*oid_a
,
2942 size_t oid_a_len
, uint8_t type_a
,
2943 const void *data_a
, size_t data_a_len
,
2944 const oid
*oid_b
, size_t oid_b_len
,
2945 uint8_t type_b
, const void *data_b
,
2948 netsnmp_variable_list
*notification_vars
= NULL
;
2949 oid var_name
[MAX_OID_LEN
];
2954 if (trap_id
!= ISIS_TRAP_ID_LEN_MISMATCH
2955 && trap_id
!= ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
2956 && trap_id
!= ISIS_TRAP_OWN_LSP_PURGE
2957 && trap_id
!= ISIS_TRAP_SEQNO_SKIPPED
2958 && trap_id
!= ISIS_TRAP_AUTHEN_TYPE_FAILURE
2959 && trap_id
!= ISIS_TRAP_AUTHEN_FAILURE
2960 && trap_id
!= ISIS_TRAP_REJ_ADJACENCY
)
2963 /* Put in trap value */
2964 memcpy(var_name
, isis_snmp_notifications
,
2965 sizeof(isis_snmp_notifications
));
2966 var_count
= array_size(isis_snmp_notifications
);
2967 var_name
[var_count
++] = trap_id
;
2969 /* Put in trap value */
2970 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2971 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2972 (uint8_t *)var_name
, var_count
* sizeof(oid
));
2974 val
= circuit
->is_type
;
2975 snmp_varlist_add_variable(
2976 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2977 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2978 (uint8_t *)&val
, sizeof(val
));
2980 if (oid_a_len
!= 0) {
2981 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
2984 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
2985 type_a
, (uint8_t *)data_a
,
2989 if (circuit
->interface
== NULL
)
2992 val
= circuit
->interface
->ifindex
;
2994 snmp_varlist_add_variable(
2995 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
2996 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
2997 (uint8_t *)&val
, sizeof(val
));
3000 if (oid_b_len
!= 0) {
3001 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3004 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3005 type_b
, (uint8_t *)data_b
,
3009 send_v2trap(notification_vars
);
3010 snmp_free_varbind(notification_vars
);
3011 smux_events_update();
3015 * A common function to handle popular combination of trap objects
3016 * isisNotificationSysLevelIndex,
3017 * isisNotificationCircIfIndex,
3021 * Note: the only difference with worker_a is order of circ-if-index vs
3024 static void isis_snmp_update_worker_b(const struct isis_circuit
*circuit
,
3025 oid trap_id
, const oid
*oid_a
,
3026 size_t oid_a_len
, uint8_t type_a
,
3027 const void *data_a
, size_t data_a_len
,
3028 const oid
*oid_b
, size_t oid_b_len
,
3029 uint8_t type_b
, const void *data_b
,
3032 netsnmp_variable_list
*notification_vars
= NULL
;
3033 oid var_name
[MAX_OID_LEN
];
3038 if (trap_id
!= ISIS_TRAP_VERSION_SKEW
3039 && trap_id
!= ISIS_TRAP_LSP_TOO_LARGE
3040 && trap_id
!= ISIS_TRAP_ADJ_STATE_CHANGE
)
3043 /* Put in trap value */
3044 memcpy(var_name
, isis_snmp_notifications
,
3045 sizeof(isis_snmp_notifications
));
3046 var_count
= array_size(isis_snmp_notifications
);
3047 var_name
[var_count
++] = trap_id
;
3049 /* Put in trap value */
3050 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3051 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3052 (uint8_t *)var_name
, var_count
* sizeof(oid
));
3054 val
= circuit
->is_type
;
3055 snmp_varlist_add_variable(
3056 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3057 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3058 (uint8_t *)&val
, sizeof(val
));
3060 if (circuit
->interface
== NULL
)
3063 val
= circuit
->interface
->ifindex
;
3065 snmp_varlist_add_variable(
3066 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3067 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3068 (uint8_t *)&val
, sizeof(val
));
3071 if (oid_a_len
!= 0) {
3072 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
3075 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
3076 type_a
, (uint8_t *)data_a
,
3080 if (oid_b_len
!= 0) {
3081 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3084 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3085 type_b
, (uint8_t *)data_b
,
3089 send_v2trap(notification_vars
);
3090 snmp_free_varbind(notification_vars
);
3091 smux_events_update();
3095 static int isis_snmp_id_len_mismatch_update(const struct isis_circuit
*circuit
,
3096 uint8_t rcv_id
, const char *raw_pdu
,
3101 if (!isis_snmp_trap_throttle(ISIS_TRAP_ID_LEN_MISMATCH
))
3106 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3107 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3109 isis_snmp_update_worker_a(
3110 circuit
, ISIS_TRAP_ID_LEN_MISMATCH
,
3111 isis_snmp_trap_data_var_pdu_field_len
,
3112 array_size(isis_snmp_trap_data_var_pdu_field_len
), UNSIGNED32
,
3113 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3114 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3115 raw_pdu
, raw_pdu_len
);
3120 isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit
*circuit
,
3121 uint8_t max_addrs
, const char *raw_pdu
,
3126 if (!isis_snmp_trap_throttle(ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
))
3131 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3132 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3134 isis_snmp_update_worker_a(
3135 circuit
, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
,
3136 isis_snmp_trap_data_var_pdu_max_area_addr
,
3137 array_size(isis_snmp_trap_data_var_pdu_max_area_addr
),
3138 UNSIGNED32
, &val
, sizeof(val
),
3139 isis_snmp_trap_data_var_pdu_fragment
,
3140 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3141 raw_pdu
, raw_pdu_len
);
3145 static int isis_snmp_own_lsp_purge_update(const struct isis_circuit
*circuit
,
3146 const uint8_t *lsp_id
)
3148 if (!isis_snmp_trap_throttle(ISIS_TRAP_OWN_LSP_PURGE
))
3151 isis_snmp_update_worker_a(
3152 circuit
, ISIS_TRAP_OWN_LSP_PURGE
, NULL
, 0, STRING
, NULL
, 0,
3153 isis_snmp_trap_data_var_pdu_lsp_id
,
3154 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3155 ISIS_SYS_ID_LEN
+ 2);
3159 static int isis_snmp_seqno_skipped_update(const struct isis_circuit
*circuit
,
3160 const uint8_t *lsp_id
)
3162 if (!isis_snmp_trap_throttle(ISIS_TRAP_SEQNO_SKIPPED
))
3165 isis_snmp_update_worker_a(
3166 circuit
, ISIS_TRAP_SEQNO_SKIPPED
, NULL
, 0, STRING
, NULL
, 0,
3167 isis_snmp_trap_data_var_pdu_lsp_id
,
3168 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3169 ISIS_SYS_ID_LEN
+ 2);
3174 isis_snmp_authentication_type_failure_update(const struct isis_circuit
*circuit
,
3175 const char *raw_pdu
,
3178 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_TYPE_FAILURE
))
3181 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3182 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3184 isis_snmp_update_worker_a(
3185 circuit
, ISIS_TRAP_AUTHEN_TYPE_FAILURE
, NULL
, 0, STRING
, NULL
,
3186 0, isis_snmp_trap_data_var_pdu_fragment
,
3187 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3188 raw_pdu
, raw_pdu_len
);
3193 isis_snmp_authentication_failure_update(const struct isis_circuit
*circuit
,
3194 char const *raw_pdu
, size_t raw_pdu_len
)
3196 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_FAILURE
))
3199 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3200 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3202 isis_snmp_update_worker_a(
3203 circuit
, ISIS_TRAP_AUTHEN_FAILURE
, NULL
, 0, STRING
, NULL
, 0,
3204 isis_snmp_trap_data_var_pdu_fragment
,
3205 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3206 raw_pdu
, raw_pdu_len
);
3210 static int isis_snmp_version_skew_update(const struct isis_circuit
*circuit
,
3211 uint8_t version
, const char *raw_pdu
,
3216 if (!isis_snmp_trap_throttle(ISIS_TRAP_VERSION_SKEW
))
3221 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3222 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3224 isis_snmp_update_worker_b(
3225 circuit
, ISIS_TRAP_VERSION_SKEW
,
3226 isis_snmp_trap_data_var_pdu_proto_ver
,
3227 array_size(isis_snmp_trap_data_var_pdu_proto_ver
), UNSIGNED32
,
3228 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3229 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3230 raw_pdu
, raw_pdu_len
);
3234 static int isis_snmp_area_mismatch_update(const struct isis_circuit
*circuit
,
3235 const char *raw_pdu
,
3239 * This is a special case because
3240 * it does not include isisNotificationSysLevelIndex
3242 netsnmp_variable_list
*notification_vars
;
3245 if (!isis_snmp_trap_throttle(ISIS_TRAP_AREA_MISMATCH
))
3248 notification_vars
= NULL
;
3250 /* Put in trap value */
3251 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3252 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3253 (uint8_t *)&isis_snmp_trap_val_area_mismatch
,
3254 sizeof(isis_snmp_trap_val_area_mismatch
));
3257 if (circuit
->interface
== NULL
)
3260 val
= circuit
->interface
->ifindex
;
3262 snmp_varlist_add_variable(
3263 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3264 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3265 (uint8_t *)&val
, sizeof(val
));
3268 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3269 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3271 snmp_varlist_add_variable(
3272 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3273 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3274 raw_pdu
, raw_pdu_len
);
3276 send_v2trap(notification_vars
);
3277 snmp_free_varbind(notification_vars
);
3278 smux_events_update();
3283 static int isis_snmp_reject_adjacency_update(const struct isis_circuit
*circuit
,
3284 const char *raw_pdu
,
3287 if (!isis_snmp_trap_throttle(ISIS_TRAP_REJ_ADJACENCY
))
3290 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3291 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3293 isis_snmp_update_worker_a(
3294 circuit
, ISIS_TRAP_REJ_ADJACENCY
, NULL
, 0, STRING
, NULL
, 0,
3295 isis_snmp_trap_data_var_pdu_fragment
,
3296 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3297 raw_pdu
, raw_pdu_len
);
3301 static int isis_snmp_lsp_too_large_update(const struct isis_circuit
*circuit
,
3303 const uint8_t *lsp_id
)
3305 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_TOO_LARGE
))
3308 isis_snmp_update_worker_b(
3309 circuit
, ISIS_TRAP_LSP_TOO_LARGE
,
3310 isis_snmp_trap_data_var_pdu_lsp_size
,
3311 array_size(isis_snmp_trap_data_var_pdu_lsp_size
), UNSIGNED32
,
3312 &pdu_size
, sizeof(pdu_size
), isis_snmp_trap_data_var_pdu_lsp_id
,
3313 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3314 ISIS_SYS_ID_LEN
+ 2);
3319 static int isis_snmp_adj_state_change_update(const struct isis_adjacency
*adj
)
3321 uint8_t lsp_id
[ISIS_SYS_ID_LEN
+ 2];
3323 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
3325 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
3329 memcpy(lsp_id
, adj
->sysid
, ISIS_SYS_ID_LEN
);
3330 lsp_id
[ISIS_SYS_ID_LEN
] = 0;
3331 lsp_id
[ISIS_SYS_ID_LEN
+ 1] = 0;
3333 val
= isis_snmp_adj_state(adj
->adj_state
);
3335 isis_snmp_update_worker_b(
3336 adj
->circuit
, ISIS_TRAP_ADJ_STATE_CHANGE
,
3337 isis_snmp_trap_data_var_pdu_lsp_id
,
3338 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3339 ISIS_SYS_ID_LEN
+ 2, isis_snmp_trap_data_var_adj_state
,
3340 array_size(isis_snmp_trap_data_var_adj_state
), INTEGER
, &val
,
3345 static int isis_snmp_lsp_error_update(const struct isis_circuit
*circuit
,
3346 const uint8_t *lsp_id
,
3347 char const *raw_pdu
, size_t raw_pdu_len
)
3350 * This is a special case because
3351 * it have more variables
3353 netsnmp_variable_list
*notification_vars
;
3356 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_ERROR
))
3359 notification_vars
= NULL
;
3361 /* Put in trap value */
3362 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3363 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3364 (uint8_t *)&isis_snmp_trap_val_lsp_error
,
3365 sizeof(isis_snmp_trap_val_lsp_error
));
3368 val
= circuit
->is_type
;
3370 snmp_varlist_add_variable(
3371 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3372 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3373 (uint8_t *)&val
, sizeof(val
));
3376 snmp_varlist_add_variable(
3377 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
3378 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3379 ISIS_SYS_ID_LEN
+ 2);
3382 if (circuit
->interface
== NULL
)
3385 val
= circuit
->interface
->ifindex
;
3387 snmp_varlist_add_variable(
3388 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3389 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3390 (uint8_t *)&val
, sizeof(val
));
3393 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3394 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3396 snmp_varlist_add_variable(
3397 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3398 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3399 raw_pdu
, raw_pdu_len
);
3404 snmp_varlist_add_variable(
3405 ¬ification_vars
, isis_snmp_trap_data_var_error_offset
,
3406 array_size(isis_snmp_trap_data_var_error_offset
), UNSIGNED32
,
3407 (uint8_t *)&val
, sizeof(val
));
3412 snmp_varlist_add_variable(
3413 ¬ification_vars
, isis_snmp_trap_data_var_error_tlv_type
,
3414 array_size(isis_snmp_trap_data_var_error_tlv_type
), UNSIGNED32
,
3415 (uint8_t *)&val
, sizeof(val
));
3417 send_v2trap(notification_vars
);
3418 snmp_free_varbind(notification_vars
);
3419 smux_events_update();
3424 static int isis_snmp_module_init(void)
3426 hook_register(isis_hook_db_overload
, isis_snmp_db_overload_update
);
3427 hook_register(isis_hook_lsp_exceed_max
,
3428 isis_snmp_lsp_exceed_max_update
);
3429 hook_register(isis_hook_id_len_mismatch
,
3430 isis_snmp_id_len_mismatch_update
);
3431 hook_register(isis_hook_max_area_addr_mismatch
,
3432 isis_snmp_max_area_addr_mismatch_update
);
3433 hook_register(isis_hook_own_lsp_purge
, isis_snmp_own_lsp_purge_update
);
3434 hook_register(isis_hook_seqno_skipped
, isis_snmp_seqno_skipped_update
);
3435 hook_register(isis_hook_authentication_type_failure
,
3436 isis_snmp_authentication_type_failure_update
);
3437 hook_register(isis_hook_authentication_failure
,
3438 isis_snmp_authentication_failure_update
);
3439 hook_register(isis_hook_version_skew
, isis_snmp_version_skew_update
);
3440 hook_register(isis_hook_area_mismatch
, isis_snmp_area_mismatch_update
);
3441 hook_register(isis_hook_reject_adjacency
,
3442 isis_snmp_reject_adjacency_update
);
3443 hook_register(isis_hook_lsp_too_large
, isis_snmp_lsp_too_large_update
);
3444 hook_register(isis_hook_adj_state_change
,
3445 isis_snmp_adj_state_change_update
);
3446 hook_register(isis_hook_lsp_error
, isis_snmp_lsp_error_update
);
3447 hook_register(isis_circuit_new_hook
, isis_circuit_snmp_id_gen
);
3448 hook_register(isis_circuit_del_hook
, isis_circuit_snmp_id_free
);
3450 hook_register(frr_late_init
, isis_snmp_init
);
3455 .name
= "isis_snmp",
3456 .version
= FRR_VERSION
,
3457 .description
= "isis AgentX SNMP module",
3458 .init
= isis_snmp_module_init
,