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 area_addr
**ret_addr
)
838 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
840 struct isis_area
*area
= NULL
;
841 struct area_addr
*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 area_addr
**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 area_addr
*found_addr
= NULL
;
891 struct area_addr
*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 area_addr
*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 *write_method
= NULL
;
2490 if (*length
<= v
->namelen
) {
2493 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2497 oid_idx
= name
+ v
->namelen
;
2498 oid_idx_len
= *length
- v
->namelen
;
2501 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2502 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2505 if (!res
|| oid_idx_len
!= 2)
2509 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2510 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2515 /* Copy the name out */
2516 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2519 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2520 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2523 *length
= v
->namelen
+ 2;
2527 case ISIS_ISADJ_STATE
:
2528 return SNMP_INTEGER(isis_snmp_adj_state(adj
->adj_state
));
2530 case ISIS_ISADJ_3WAYSTATE
:
2531 return SNMP_INTEGER(adj
->threeway_state
);
2533 case ISIS_ISADJ_NEIGHSNPAADDRESS
: {
2534 const char *snpa
= (char *)snpa_print(adj
->snpa
);
2535 *var_len
= strlen(snpa
);
2536 return (uint8_t *)snpa
;
2539 case ISIS_ISADJ_NEIGHSYSTYPE
:
2540 return SNMP_INTEGER(isis_snmp_adj_neightype(adj
->sys_type
));
2542 case ISIS_ISADJ_NEIGHSYSID
:
2543 *var_len
= sizeof(adj
->sysid
);
2546 case ISIS_ISADJ_NBREXTENDEDCIRCID
:
2547 return SNMP_INTEGER(adj
->ext_circuit_id
!= 0 ? 1 : 0);
2549 case ISIS_ISADJ_USAGE
:
2550 /* It seems that no value conversion is required */
2551 return SNMP_INTEGER(adj
->adj_usage
);
2553 case ISIS_ISADJ_HOLDTIMER
:
2555 * It seems that we want remaining timer
2557 if (adj
->last_upd
!= 0) {
2559 if (val
< (adj
->last_upd
+ adj
->hold_time
))
2560 return SNMP_INTEGER(adj
->last_upd
2561 + adj
->hold_time
- val
);
2563 /* Not running or just expired */
2564 return SNMP_INTEGER(0);
2566 case ISIS_ISADJ_NEIGHPRIORITY
:
2567 return SNMP_INTEGER(adj
->prio
[adj
->level
- 1]);
2569 case ISIS_ISADJ_LASTUPTIME
:
2570 if (adj
->flaps
== 0)
2571 return SNMP_INTEGER(0);
2573 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2575 now_time
= time(NULL
);
2577 if (adj
->last_flap
>= now_time
)
2578 return SNMP_INTEGER(up_ticks
);
2580 delta_ticks
= (now_time
- adj
->last_flap
) * 10;
2582 if (up_ticks
< delta_ticks
)
2583 return SNMP_INTEGER(up_ticks
);
2585 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2594 static uint8_t *isis_snmp_find_isadj_area(struct variable
*v
, oid
*name
,
2595 size_t *length
, int exact
,
2597 WriteMethod
**write_method
)
2599 /* Index circuit-id: 1-255 + adj-id: 1-... */
2603 struct isis_adjacency
*adj
;
2608 *write_method
= NULL
;
2610 if (*length
<= v
->namelen
) {
2613 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2617 oid_idx
= name
+ v
->namelen
;
2618 oid_idx_len
= *length
- v
->namelen
;
2621 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2622 ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2623 &adj
, NULL
, &data
, &data_len
);
2625 if (!res
|| oid_idx_len
!= 3)
2629 res
= isis_snmp_adj_lookup_next(
2630 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2631 &adj
, &data_idx
, &data
, &data_len
);
2635 /* Copy the name out */
2636 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2639 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2640 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2641 name
[v
->namelen
+ 2] = data_idx
;
2644 *length
= v
->namelen
+ 3;
2648 case ISIS_ISADJAREA_ADDRESS
:
2649 *var_len
= data_len
;
2659 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*v
, oid
*name
,
2660 size_t *length
, int exact
,
2662 WriteMethod
**write_method
)
2664 /* Index circuit-id 1-255 + adj-id 1-... */
2668 struct isis_adjacency
*adj
;
2673 *write_method
= NULL
;
2675 if (*length
<= v
->namelen
) {
2678 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2682 oid_idx
= name
+ v
->namelen
;
2683 oid_idx_len
= *length
- v
->namelen
;
2686 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2687 ISIS_SNMP_ADJ_DATA_IP_ADDR
,
2688 &adj
, NULL
, &data
, &data_len
);
2690 if (!res
|| oid_idx_len
!= 3)
2693 res
= isis_snmp_adj_lookup_next(
2694 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_IP_ADDR
, &adj
,
2695 &data_idx
, &data
, &data_len
);
2699 /* Copy the name out */
2700 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2703 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2704 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2705 name
[v
->namelen
+ 2] = data_idx
;
2708 *length
= v
->namelen
+ 3;
2712 case ISIS_ISADJIPADDR_TYPE
:
2714 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V4
);
2716 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V6
);
2718 case ISIS_ISADJIPADDR_ADDRESS
:
2719 *var_len
= data_len
;
2729 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*v
, oid
*name
,
2730 size_t *length
, int exact
,
2732 WriteMethod
**write_method
)
2734 /* Index circuit-id 1-255 + adj-id 1-... */
2738 struct isis_adjacency
*adj
;
2743 *write_method
= NULL
;
2745 if (*length
<= v
->namelen
) {
2748 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2752 oid_idx
= name
+ v
->namelen
;
2753 oid_idx_len
= *length
- v
->namelen
;
2756 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2757 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2758 NULL
, &data
, &data_len
);
2760 if (!res
|| oid_idx_len
!= 3)
2764 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2765 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2766 &data_idx
, &data
, &data_len
);
2770 /* Copy the name out */
2771 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2774 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2775 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2776 name
[v
->namelen
+ 2] = data_idx
;
2779 *length
= v
->namelen
+ 3;
2783 case ISIS_ISADJPROTSUPP_PROTOCOL
:
2784 return SNMP_INTEGER(*data
);
2794 /* Register ISIS-MIB. */
2795 static int isis_snmp_init(struct event_loop
*tm
)
2797 struct isis_func_to_prefix
*h2f
= isis_func_to_prefix_arr
;
2800 for (size_t off
= 0; off
< isis_var_count
; off
++) {
2801 v
= &isis_var_arr
[off
];
2803 if (v
->findVar
!= h2f
->ihtp_func
) {
2806 assert(h2f
< (isis_func_to_prefix_arr
2807 + isis_func_to_prefix_count
));
2808 assert(v
->findVar
== h2f
->ihtp_func
);
2811 v
->namelen
= h2f
->ihtp_pref_len
+ 1;
2812 memcpy(v
->name
, h2f
->ihtp_pref_oid
,
2813 h2f
->ihtp_pref_len
* sizeof(oid
));
2814 v
->name
[h2f
->ihtp_pref_len
] = v
->magic
;
2819 REGISTER_MIB("mibII/isis", isis_var_arr
, variable
, isis_oid
);
2824 * ISIS notification functions: we have one function per notification
2826 static int isis_snmp_trap_throttle(oid trap_id
)
2829 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2831 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
2834 time_now
= time(NULL
);
2836 if ((isis_snmp_trap_timestamp
[trap_id
] + 5) > time_now
)
2837 /* Throttle trap rate at 1 in 5 secs */
2840 isis_snmp_trap_timestamp
[trap_id
] = time_now
;
2844 static int isis_snmp_db_overload_update(const struct isis_area
*area
)
2846 netsnmp_variable_list
*notification_vars
;
2850 if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD
))
2853 notification_vars
= NULL
;
2855 /* Put in trap value */
2856 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2857 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2858 (uint8_t *)&isis_snmp_trap_val_db_overload
,
2859 sizeof(isis_snmp_trap_val_db_overload
));
2862 val
= area
->is_type
;
2864 snmp_varlist_add_variable(
2865 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2866 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2867 (uint8_t *)&val
, sizeof(val
));
2869 /* Patch sys_level_state with proper index */
2870 off
= array_size(isis_snmp_trap_data_var_sys_level_state
) - 1;
2871 isis_snmp_trap_data_var_sys_level_state
[off
] = val
;
2874 if (area
->overload_bit
)
2875 val
= ISIS_SNMP_LEVEL_STATE_OVERLOADED
;
2877 val
= ISIS_SNMP_LEVEL_STATE_ON
;
2879 snmp_varlist_add_variable(
2880 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_state
,
2881 array_size(isis_snmp_trap_data_var_sys_level_state
), INTEGER
,
2882 (uint8_t *)&val
, sizeof(val
));
2884 send_v2trap(notification_vars
);
2885 snmp_free_varbind(notification_vars
);
2886 smux_events_update();
2890 static int isis_snmp_lsp_exceed_max_update(const struct isis_area
*area
,
2891 const uint8_t *lsp_id
)
2893 netsnmp_variable_list
*notification_vars
;
2896 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_EXCEED_MAX
))
2899 notification_vars
= NULL
;
2901 /* Put in trap value */
2902 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2903 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2904 (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max
,
2905 sizeof(isis_snmp_trap_val_lsp_exceed_max
));
2908 val
= area
->is_type
;
2910 snmp_varlist_add_variable(
2911 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2912 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2913 (uint8_t *)&val
, sizeof(val
));
2915 snmp_varlist_add_variable(
2916 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
2917 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
2918 ISIS_SYS_ID_LEN
+ 2);
2920 send_v2trap(notification_vars
);
2921 snmp_free_varbind(notification_vars
);
2922 smux_events_update();
2928 * A common function to handle popular combination of trap objects
2929 * isisNotificationSysLevelIndex,
2931 * isisNotificationCircIfIndex,
2934 static void isis_snmp_update_worker_a(const struct isis_circuit
*circuit
,
2935 oid trap_id
, const oid
*oid_a
,
2936 size_t oid_a_len
, uint8_t type_a
,
2937 const void *data_a
, size_t data_a_len
,
2938 const oid
*oid_b
, size_t oid_b_len
,
2939 uint8_t type_b
, const void *data_b
,
2942 netsnmp_variable_list
*notification_vars
= NULL
;
2943 oid var_name
[MAX_OID_LEN
];
2948 if (trap_id
!= ISIS_TRAP_ID_LEN_MISMATCH
2949 && trap_id
!= ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
2950 && trap_id
!= ISIS_TRAP_OWN_LSP_PURGE
2951 && trap_id
!= ISIS_TRAP_SEQNO_SKIPPED
2952 && trap_id
!= ISIS_TRAP_AUTHEN_TYPE_FAILURE
2953 && trap_id
!= ISIS_TRAP_AUTHEN_FAILURE
2954 && trap_id
!= ISIS_TRAP_REJ_ADJACENCY
)
2957 /* Put in trap value */
2958 memcpy(var_name
, isis_snmp_notifications
,
2959 sizeof(isis_snmp_notifications
));
2960 var_count
= array_size(isis_snmp_notifications
);
2961 var_name
[var_count
++] = trap_id
;
2963 /* Put in trap value */
2964 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2965 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2966 (uint8_t *)var_name
, var_count
* sizeof(oid
));
2968 val
= circuit
->is_type
;
2969 snmp_varlist_add_variable(
2970 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2971 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2972 (uint8_t *)&val
, sizeof(val
));
2974 if (oid_a_len
!= 0) {
2975 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
2978 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
2979 type_a
, (uint8_t *)data_a
,
2983 if (circuit
->interface
== NULL
)
2986 val
= circuit
->interface
->ifindex
;
2988 snmp_varlist_add_variable(
2989 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
2990 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
2991 (uint8_t *)&val
, sizeof(val
));
2994 if (oid_b_len
!= 0) {
2995 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
2998 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
2999 type_b
, (uint8_t *)data_b
,
3003 send_v2trap(notification_vars
);
3004 snmp_free_varbind(notification_vars
);
3005 smux_events_update();
3009 * A common function to handle popular combination of trap objects
3010 * isisNotificationSysLevelIndex,
3011 * isisNotificationCircIfIndex,
3015 * Note: the only difference with worker_a is order of circ-if-index vs
3018 static void isis_snmp_update_worker_b(const struct isis_circuit
*circuit
,
3019 oid trap_id
, const oid
*oid_a
,
3020 size_t oid_a_len
, uint8_t type_a
,
3021 const void *data_a
, size_t data_a_len
,
3022 const oid
*oid_b
, size_t oid_b_len
,
3023 uint8_t type_b
, const void *data_b
,
3026 netsnmp_variable_list
*notification_vars
= NULL
;
3027 oid var_name
[MAX_OID_LEN
];
3032 if (trap_id
!= ISIS_TRAP_VERSION_SKEW
3033 && trap_id
!= ISIS_TRAP_LSP_TOO_LARGE
3034 && trap_id
!= ISIS_TRAP_ADJ_STATE_CHANGE
)
3037 /* Put in trap value */
3038 memcpy(var_name
, isis_snmp_notifications
,
3039 sizeof(isis_snmp_notifications
));
3040 var_count
= array_size(isis_snmp_notifications
);
3041 var_name
[var_count
++] = trap_id
;
3043 /* Put in trap value */
3044 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3045 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3046 (uint8_t *)var_name
, var_count
* sizeof(oid
));
3048 val
= circuit
->is_type
;
3049 snmp_varlist_add_variable(
3050 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3051 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3052 (uint8_t *)&val
, sizeof(val
));
3054 if (circuit
->interface
== NULL
)
3057 val
= circuit
->interface
->ifindex
;
3059 snmp_varlist_add_variable(
3060 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3061 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3062 (uint8_t *)&val
, sizeof(val
));
3065 if (oid_a_len
!= 0) {
3066 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
3069 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
3070 type_a
, (uint8_t *)data_a
,
3074 if (oid_b_len
!= 0) {
3075 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3078 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3079 type_b
, (uint8_t *)data_b
,
3083 send_v2trap(notification_vars
);
3084 snmp_free_varbind(notification_vars
);
3085 smux_events_update();
3089 static int isis_snmp_id_len_mismatch_update(const struct isis_circuit
*circuit
,
3090 uint8_t rcv_id
, const char *raw_pdu
,
3095 if (!isis_snmp_trap_throttle(ISIS_TRAP_ID_LEN_MISMATCH
))
3100 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3101 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3103 isis_snmp_update_worker_a(
3104 circuit
, ISIS_TRAP_ID_LEN_MISMATCH
,
3105 isis_snmp_trap_data_var_pdu_field_len
,
3106 array_size(isis_snmp_trap_data_var_pdu_field_len
), UNSIGNED32
,
3107 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3108 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3109 raw_pdu
, raw_pdu_len
);
3114 isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit
*circuit
,
3115 uint8_t max_addrs
, const char *raw_pdu
,
3120 if (!isis_snmp_trap_throttle(ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
))
3125 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3126 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3128 isis_snmp_update_worker_a(
3129 circuit
, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
,
3130 isis_snmp_trap_data_var_pdu_max_area_addr
,
3131 array_size(isis_snmp_trap_data_var_pdu_max_area_addr
),
3132 UNSIGNED32
, &val
, sizeof(val
),
3133 isis_snmp_trap_data_var_pdu_fragment
,
3134 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3135 raw_pdu
, raw_pdu_len
);
3139 static int isis_snmp_own_lsp_purge_update(const struct isis_circuit
*circuit
,
3140 const uint8_t *lsp_id
)
3142 if (!isis_snmp_trap_throttle(ISIS_TRAP_OWN_LSP_PURGE
))
3145 isis_snmp_update_worker_a(
3146 circuit
, ISIS_TRAP_OWN_LSP_PURGE
, NULL
, 0, STRING
, NULL
, 0,
3147 isis_snmp_trap_data_var_pdu_lsp_id
,
3148 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3149 ISIS_SYS_ID_LEN
+ 2);
3153 static int isis_snmp_seqno_skipped_update(const struct isis_circuit
*circuit
,
3154 const uint8_t *lsp_id
)
3156 if (!isis_snmp_trap_throttle(ISIS_TRAP_SEQNO_SKIPPED
))
3159 isis_snmp_update_worker_a(
3160 circuit
, ISIS_TRAP_SEQNO_SKIPPED
, NULL
, 0, STRING
, NULL
, 0,
3161 isis_snmp_trap_data_var_pdu_lsp_id
,
3162 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3163 ISIS_SYS_ID_LEN
+ 2);
3168 isis_snmp_authentication_type_failure_update(const struct isis_circuit
*circuit
,
3169 const char *raw_pdu
,
3172 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_TYPE_FAILURE
))
3175 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3176 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3178 isis_snmp_update_worker_a(
3179 circuit
, ISIS_TRAP_AUTHEN_TYPE_FAILURE
, NULL
, 0, STRING
, NULL
,
3180 0, isis_snmp_trap_data_var_pdu_fragment
,
3181 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3182 raw_pdu
, raw_pdu_len
);
3187 isis_snmp_authentication_failure_update(const struct isis_circuit
*circuit
,
3188 char const *raw_pdu
, size_t raw_pdu_len
)
3190 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_FAILURE
))
3193 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3194 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3196 isis_snmp_update_worker_a(
3197 circuit
, ISIS_TRAP_AUTHEN_FAILURE
, NULL
, 0, STRING
, NULL
, 0,
3198 isis_snmp_trap_data_var_pdu_fragment
,
3199 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3200 raw_pdu
, raw_pdu_len
);
3204 static int isis_snmp_version_skew_update(const struct isis_circuit
*circuit
,
3205 uint8_t version
, const char *raw_pdu
,
3210 if (!isis_snmp_trap_throttle(ISIS_TRAP_VERSION_SKEW
))
3215 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3216 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3218 isis_snmp_update_worker_b(
3219 circuit
, ISIS_TRAP_VERSION_SKEW
,
3220 isis_snmp_trap_data_var_pdu_proto_ver
,
3221 array_size(isis_snmp_trap_data_var_pdu_proto_ver
), UNSIGNED32
,
3222 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3223 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3224 raw_pdu
, raw_pdu_len
);
3228 static int isis_snmp_area_mismatch_update(const struct isis_circuit
*circuit
,
3229 const char *raw_pdu
,
3233 * This is a special case because
3234 * it does not include isisNotificationSysLevelIndex
3236 netsnmp_variable_list
*notification_vars
;
3239 if (!isis_snmp_trap_throttle(ISIS_TRAP_AREA_MISMATCH
))
3242 notification_vars
= NULL
;
3244 /* Put in trap value */
3245 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3246 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3247 (uint8_t *)&isis_snmp_trap_val_area_mismatch
,
3248 sizeof(isis_snmp_trap_val_area_mismatch
));
3251 if (circuit
->interface
== NULL
)
3254 val
= circuit
->interface
->ifindex
;
3256 snmp_varlist_add_variable(
3257 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3258 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3259 (uint8_t *)&val
, sizeof(val
));
3262 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3263 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3265 snmp_varlist_add_variable(
3266 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3267 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3268 raw_pdu
, raw_pdu_len
);
3270 send_v2trap(notification_vars
);
3271 snmp_free_varbind(notification_vars
);
3272 smux_events_update();
3277 static int isis_snmp_reject_adjacency_update(const struct isis_circuit
*circuit
,
3278 const char *raw_pdu
,
3281 if (!isis_snmp_trap_throttle(ISIS_TRAP_REJ_ADJACENCY
))
3284 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3285 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3287 isis_snmp_update_worker_a(
3288 circuit
, ISIS_TRAP_REJ_ADJACENCY
, NULL
, 0, STRING
, NULL
, 0,
3289 isis_snmp_trap_data_var_pdu_fragment
,
3290 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3291 raw_pdu
, raw_pdu_len
);
3295 static int isis_snmp_lsp_too_large_update(const struct isis_circuit
*circuit
,
3297 const uint8_t *lsp_id
)
3299 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_TOO_LARGE
))
3302 isis_snmp_update_worker_b(
3303 circuit
, ISIS_TRAP_LSP_TOO_LARGE
,
3304 isis_snmp_trap_data_var_pdu_lsp_size
,
3305 array_size(isis_snmp_trap_data_var_pdu_lsp_size
), UNSIGNED32
,
3306 &pdu_size
, sizeof(pdu_size
), isis_snmp_trap_data_var_pdu_lsp_id
,
3307 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3308 ISIS_SYS_ID_LEN
+ 2);
3313 static int isis_snmp_adj_state_change_update(const struct isis_adjacency
*adj
)
3315 uint8_t lsp_id
[ISIS_SYS_ID_LEN
+ 2];
3317 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
3319 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
3323 memcpy(lsp_id
, adj
->sysid
, ISIS_SYS_ID_LEN
);
3324 lsp_id
[ISIS_SYS_ID_LEN
] = 0;
3325 lsp_id
[ISIS_SYS_ID_LEN
+ 1] = 0;
3327 val
= isis_snmp_adj_state(adj
->adj_state
);
3329 isis_snmp_update_worker_b(
3330 adj
->circuit
, ISIS_TRAP_ADJ_STATE_CHANGE
,
3331 isis_snmp_trap_data_var_pdu_lsp_id
,
3332 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3333 ISIS_SYS_ID_LEN
+ 2, isis_snmp_trap_data_var_adj_state
,
3334 array_size(isis_snmp_trap_data_var_adj_state
), INTEGER
, &val
,
3339 static int isis_snmp_lsp_error_update(const struct isis_circuit
*circuit
,
3340 const uint8_t *lsp_id
,
3341 char const *raw_pdu
, size_t raw_pdu_len
)
3344 * This is a special case because
3345 * it have more variables
3347 netsnmp_variable_list
*notification_vars
;
3350 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_ERROR
))
3353 notification_vars
= NULL
;
3355 /* Put in trap value */
3356 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3357 array_size(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3358 (uint8_t *)&isis_snmp_trap_val_lsp_error
,
3359 sizeof(isis_snmp_trap_val_lsp_error
));
3362 val
= circuit
->is_type
;
3364 snmp_varlist_add_variable(
3365 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3366 array_size(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3367 (uint8_t *)&val
, sizeof(val
));
3370 snmp_varlist_add_variable(
3371 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
3372 array_size(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3373 ISIS_SYS_ID_LEN
+ 2);
3376 if (circuit
->interface
== NULL
)
3379 val
= circuit
->interface
->ifindex
;
3381 snmp_varlist_add_variable(
3382 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3383 array_size(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3384 (uint8_t *)&val
, sizeof(val
));
3387 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3388 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3390 snmp_varlist_add_variable(
3391 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3392 array_size(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3393 raw_pdu
, raw_pdu_len
);
3398 snmp_varlist_add_variable(
3399 ¬ification_vars
, isis_snmp_trap_data_var_error_offset
,
3400 array_size(isis_snmp_trap_data_var_error_offset
), UNSIGNED32
,
3401 (uint8_t *)&val
, sizeof(val
));
3406 snmp_varlist_add_variable(
3407 ¬ification_vars
, isis_snmp_trap_data_var_error_tlv_type
,
3408 array_size(isis_snmp_trap_data_var_error_tlv_type
), UNSIGNED32
,
3409 (uint8_t *)&val
, sizeof(val
));
3411 send_v2trap(notification_vars
);
3412 snmp_free_varbind(notification_vars
);
3413 smux_events_update();
3418 static int isis_snmp_module_init(void)
3420 hook_register(isis_hook_db_overload
, isis_snmp_db_overload_update
);
3421 hook_register(isis_hook_lsp_exceed_max
,
3422 isis_snmp_lsp_exceed_max_update
);
3423 hook_register(isis_hook_id_len_mismatch
,
3424 isis_snmp_id_len_mismatch_update
);
3425 hook_register(isis_hook_max_area_addr_mismatch
,
3426 isis_snmp_max_area_addr_mismatch_update
);
3427 hook_register(isis_hook_own_lsp_purge
, isis_snmp_own_lsp_purge_update
);
3428 hook_register(isis_hook_seqno_skipped
, isis_snmp_seqno_skipped_update
);
3429 hook_register(isis_hook_authentication_type_failure
,
3430 isis_snmp_authentication_type_failure_update
);
3431 hook_register(isis_hook_authentication_failure
,
3432 isis_snmp_authentication_failure_update
);
3433 hook_register(isis_hook_version_skew
, isis_snmp_version_skew_update
);
3434 hook_register(isis_hook_area_mismatch
, isis_snmp_area_mismatch_update
);
3435 hook_register(isis_hook_reject_adjacency
,
3436 isis_snmp_reject_adjacency_update
);
3437 hook_register(isis_hook_lsp_too_large
, isis_snmp_lsp_too_large_update
);
3438 hook_register(isis_hook_adj_state_change
,
3439 isis_snmp_adj_state_change_update
);
3440 hook_register(isis_hook_lsp_error
, isis_snmp_lsp_error_update
);
3441 hook_register(isis_circuit_new_hook
, isis_circuit_snmp_id_gen
);
3442 hook_register(isis_circuit_del_hook
, isis_circuit_snmp_id_free
);
3444 hook_register(frr_late_init
, isis_snmp_init
);
3449 .name
= "isis_snmp",
3450 .version
= FRR_VERSION
,
3451 .description
= "isis AgentX SNMP module",
3452 .init
= isis_snmp_module_init
,