3 * Copyright (C) 2020 Volta Networks, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * This is minimal read-only implementations providing isisReadOnlyCompliance
27 #include <net-snmp/net-snmp-config.h>
28 #include <net-snmp/net-snmp-includes.h>
39 #include "lib/version.h"
41 #include "isisd/isis_constants.h"
42 #include "isisd/isis_common.h"
43 #include "isisd/isis_flags.h"
44 #include "isisd/isis_circuit.h"
45 #include "isisd/isis_lsp.h"
46 #include "isisd/isis_pdu.h"
47 #include "isisd/isis_network.h"
48 #include "isisd/isis_misc.h"
49 #include "isisd/isis_constants.h"
50 #include "isisd/isis_adjacency.h"
51 #include "isisd/isis_dynhn.h"
52 #include "isisd/isis_te.h"
53 #include "isisd/isis_dr.h"
54 #include "isisd/isis_nb.h"
55 #include "isisd/isisd.h"
58 #define ISIS_MIB 1, 3, 6, 1, 2, 1, 138
60 #define ISIS_OBJECTS 1
61 #define ISIS_SYSTEM 1, 1
62 #define ISIS_SYSLEVEL 1, 2
63 #define ISIS_CIRC 1, 3
64 #define ISIS_CIRC_LEVEL_VALUES 1, 4
65 #define ISIS_COUNTERS 1, 5
66 #define ISIS_ISADJ 1, 6
68 /************************ isisSystemGroup ************************/
71 #define ISIS_SYS_OBJECT 1, 1, 1
72 #define ISIS_SYS_VERSION 1
73 #define ISIS_SYS_LEVELTYPE 2
75 #define ISIS_SYS_MAXPATHSPLITS 4
76 #define ISIS_SYS_MAXLSPGENINT 5
77 #define ISIS_SYS_POLLESHELLORATE 6
78 #define ISIS_SYS_WAITTIME 7
79 #define ISIS_SYS_ADMINSTATE 8
80 #define ISIS_SYS_L2TOL1LEAKING 9
81 #define ISIS_SYS_MAXAGE 10
82 #define ISIS_SYS_RECEIVELSPBUFFERSIZE 11
83 #define ISIS_SYS_PROTSUPPORTED 12
84 #define ISIS_SYS_NOTIFICATIONENABLE 13
86 /* isisManAreaAddrEntry */
87 #define ISIS_MANAREA_ADDRENTRY 1, 1, 2, 1
88 #define ISIS_MANAREA_ADDREXISTSTATE 2
90 /* isisAreaAddrEntry */
91 #define ISIS_AREA_ADDRENTRY 1, 1, 3, 1
92 #define ISIS_AREA_ADDR 1
94 /* isisSummAddrEntry */
95 #define ISIS_SUMM_ADDRENTRY 1, 1, 4, 1
96 #define ISIS_SUMM_ADDREXISTSTATE 4
97 #define ISIS_SUMM_ADDRMETRIC 5
98 #define ISIS_SUMM_ADDRFULLMETRIC 6
100 /* isisRedistributeAddrEntry */
101 #define ISIS_REDISTRIBUTE_ADDRENTRY 1, 1, 5, 1
102 #define ISIS_REDISTRIBUTE_ADDREXISTSTATE 3
104 /* isisRouterEntry */
105 #define ISIS_ROUTER_ENTRY 1, 1, 6, 1
106 #define ISIS_ROUTER_HOSTNAME 3
107 #define ISIS_ROUTER_ID 4
109 /* isisSysLevelTable */
110 #define ISIS_SYSLEVEL_ENTRY 1, 2, 1, 1
111 #define ISIS_SYSLEVEL_ORIGLSPBUFFSIZE 2
112 #define ISIS_SYSLEVEL_MINLSPGENINT 3
113 #define ISIS_SYSLEVEL_STATE 4
114 #define ISIS_SYSLEVEL_SETOVERLOAD 5
115 #define ISIS_SYSLEVEL_SETOVERLOADUNTIL 6
116 #define ISIS_SYSLEVEL_METRICSTYLE 7
117 #define ISIS_SYSLEVEL_SPFCONSIDERS 8
118 #define ISIS_SYSLEVEL_TEENABLED 9
121 /* isisSystemCounterEntry */
122 #define ISIS_SYSTEM_COUNTER_ENTRY 1, 5, 1, 1
123 #define ISIS_SYSSTAT_CORRLSPS 2
124 #define ISIS_SYSSTAT_AUTHTYPEFAILS 3
125 #define ISIS_SYSSTAT_AUTHFAILS 4
126 #define ISIS_SYSSTAT_LSPDBASEOLOADS 5
127 #define ISIS_SYSSTAT_MANADDRDROPFROMAREAS 6
128 #define ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS 7
129 #define ISIS_SYSSTAT_SEQNUMSKIPS 8
130 #define ISIS_SYSSTAT_OWNLSPPURGES 9
131 #define ISIS_SYSSTAT_IDFIELDLENMISMATCHES 10
132 #define ISIS_SYSSTAT_PARTCHANGES 11
133 #define ISIS_SYSSTAT_SPFRUNS 12
134 #define ISIS_SYSSTAT_LSPERRORS 13
137 /************************ isisCircuitGroup ************************/
139 /* Scalar directly under isisCirc */
140 #define ISIS_NEXTCIRC_INDEX 1
143 #define ISIS_CIRC_ENTRY 1, 3, 2, 1
144 #define ISIS_CIRC_IFINDEX 2
145 #define ISIS_CIRC_ADMINSTATE 3
146 #define ISIS_CIRC_EXISTSTATE 4
147 #define ISIS_CIRC_TYPE 5
148 #define ISIS_CIRC_EXTDOMAIN 6
149 #define ISIS_CIRC_LEVELTYPE 7
150 #define ISIS_CIRC_PASSIVECIRCUIT 8
151 #define ISIS_CIRC_MESHGROUPENABLED 9
152 #define ISIS_CIRC_MESHGROUP 10
153 #define ISIS_CIRC_SMALLHELLOS 11
154 #define ISIS_CIRC_LASTUPTIME 12
155 #define ISIS_CIRC_3WAYENABLED 13
156 #define ISIS_CIRC_EXTENDEDCIRCID 14
158 /* isisCircLevelEntry */
159 #define ISIS_CIRCLEVEL_ENTRY 1, 4, 1, 1
160 #define ISIS_CIRCLEVEL_METRIC 2
161 #define ISIS_CIRCLEVEL_WIDEMETRIC 3
162 #define ISIS_CIRCLEVEL_ISPRIORITY 4
163 #define ISIS_CIRCLEVEL_IDOCTET 5
164 #define ISIS_CIRCLEVEL_ID 6
165 #define ISIS_CIRCLEVEL_DESIS 7
166 #define ISIS_CIRCLEVEL_HELLOMULTIPLIER 8
167 #define ISIS_CIRCLEVEL_HELLOTIMER 9
168 #define ISIS_CIRCLEVEL_DRHELLOTIMER 10
169 #define ISIS_CIRCLEVEL_LSPTHROTTLE 11
170 #define ISIS_CIRCLEVEL_MINLSPRETRANSINT 12
171 #define ISIS_CIRCLEVEL_CSNPINTERVAL 13
172 #define ISIS_CIRCLEVEL_PARTSNPINTERVAL 14
174 /* isisCircuitCounterEntry */
175 #define ISIS_CIRC_COUNTER_ENTRY 1, 5, 2, 1
176 #define ISIS_CIRC_ADJCHANGES 2
177 #define ISIS_CIRC_NUMADJ 3
178 #define ISIS_CIRC_INITFAILS 4
179 #define ISIS_CIRC_REJADJS 5
180 #define ISIS_CIRC_IDFIELDLENMISMATCHES 6
181 #define ISIS_CIRC_MAXAREAADDRMISMATCHES 7
182 #define ISIS_CIRC_AUTHTYPEFAILS 8
183 #define ISIS_CIRC_AUTHFAILS 9
184 #define ISIS_CIRC_LANDESISCHANGES 10
187 /************************ isisISAdjGroup ************************/
190 #define ISIS_ISADJ_ENTRY 1, 6, 1, 1
191 #define ISIS_ISADJ_STATE 2
192 #define ISIS_ISADJ_3WAYSTATE 3
193 #define ISIS_ISADJ_NEIGHSNPAADDRESS 4
194 #define ISIS_ISADJ_NEIGHSYSTYPE 5
195 #define ISIS_ISADJ_NEIGHSYSID 6
196 #define ISIS_ISADJ_NBREXTENDEDCIRCID 7
197 #define ISIS_ISADJ_USAGE 8
198 #define ISIS_ISADJ_HOLDTIMER 9
199 #define ISIS_ISADJ_NEIGHPRIORITY 10
200 #define ISIS_ISADJ_LASTUPTIME 11
202 /* isisISAdjAreadAddrEntry */
203 #define ISIS_ISADJAREA_ADDRENTRY 1, 6, 2, 1
204 #define ISIS_ISADJAREA_ADDRESS 2
206 /* isisISAdjIPAddrEntry*/
207 #define ISIS_ISADJIPADDR_ENTRY 1, 6, 3, 1
208 #define ISIS_ISADJIPADDR_TYPE 2
209 #define ISIS_ISADJIPADDR_ADDRESS 3
212 /* isisISAdjProtSuppEntty */
214 #define ISIS_ISADJPROTSUPP_ENTRY 1, 6, 4, 1
215 #define ISIS_ISADJPROTSUPP_PROTOCOL 1
218 /************************ Trap data variables ************************/
219 #define ISIS_NOTIFICATION_ENTRY 1, 10, 1
220 #define ISIS_NOTIF_SYLELVELINDEX 1
221 #define ISIS_NOTIF_CIRCIFINDEX 2
222 #define ISIS_PDU_LSPID 3
223 #define ISIS_PDU_FRAGMENT 4
224 #define ISIS_PDU_FIELDLEN 5
225 #define ISIS_PDU_MAXAREAADDR 6
226 #define ISIS_PDU_PROTOVER 7
227 #define ISIS_PDU_LSPSIZE 8
228 #define ISIS_PDU_ORIGBUFFERSIZE 9
229 #define ISIS_PDU_BUFFERSIZE 10
230 #define ISIS_PDU_PROTSUPP 11
231 #define ISIS_ADJ_STATE 12
232 #define ISIS_ERROR_OFFSET 13
233 #define ISIS_ERROR_TLVTYPE 14
234 #define ISIS_NOTIF_AREAADDR 15
236 /************************ Traps ************************/
237 #define ISIS_NOTIFICATIONS ISIS_MIB, 0
238 #define ISIS_TRAP_DB_OVERLOAD 1
239 #define ISIS_TRAP_MAN_ADDR_DROP 2
240 #define ISIS_TRAP_CORRUPTED_LSP 3
241 #define ISIS_TRAP_LSP_EXCEED_MAX 4
242 #define ISIS_TRAP_ID_LEN_MISMATCH 5
243 #define ISIS_TRAP_MAX_AREA_ADDR_MISMATCH 6
244 #define ISIS_TRAP_OWN_LSP_PURGE 7
245 #define ISIS_TRAP_SEQNO_SKIPPED 8
246 #define ISIS_TRAP_AUTHEN_TYPE_FAILURE 9
247 #define ISIS_TRAP_AUTHEN_FAILURE 10
248 #define ISIS_TRAP_VERSION_SKEW 11
249 #define ISIS_TRAP_AREA_MISMATCH 12
250 #define ISIS_TRAP_REJ_ADJACENCY 13
251 #define ISIS_TRAP_LSP_TOO_LARGE 14
252 #define ISIS_TRAP_LSP_BUFFSIZE_MISMATCH 15
253 #define ISIS_TRAP_PROTSUPP_MISMATCH 16
254 #define ISIS_TRAP_ADJ_STATE_CHANGE 17
255 #define ISIS_TRAP_LSP_ERROR 18
257 /* Change this definition if number of traps changes */
258 #define ISIS_TRAP_LAST_TRAP ISIS_TRAP_LSP_ERROR + 1
260 #define ISIS_SNMP_TRAP_VAR 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0
263 /* SNMP value hack. */
264 #define COUNTER32 ASN_COUNTER
265 #define INTEGER ASN_INTEGER
266 #define UNSIGNED32 ASN_GAUGE
267 #define TIMESTAMP ASN_TIMETICKS
268 #define TIMETICKS ASN_TIMETICKS
269 #define STRING ASN_OCTET_STR
271 /* Declare static local variables for convenience. */
274 /* If ARRAY_SIZE is not available use a primitive substitution */
276 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
280 * Define time function, it serves two purposes
281 * 1. Uses unint32_t for unix time and encapsulates
282 * sing extension issues in conversion from time_t
284 * 2. I could be replaced in unit test environment
287 /* ISIS-MIB instances. */
288 static oid isis_oid
[] = {ISIS_MIB
};
290 /* SNMP trap variable */
291 static oid isis_snmp_trap_var
[] = {ISIS_SNMP_TRAP_VAR
};
293 /* SNMP trap values (others are calculated on the fly */
294 static oid isis_snmp_notifications
[] = {ISIS_NOTIFICATIONS
};
295 static oid isis_snmp_trap_val_db_overload
[] = {ISIS_NOTIFICATIONS
,
296 ISIS_TRAP_DB_OVERLOAD
};
297 static oid isis_snmp_trap_val_lsp_exceed_max
[] = {ISIS_NOTIFICATIONS
,
298 ISIS_TRAP_LSP_EXCEED_MAX
};
299 static oid isis_snmp_trap_val_area_mismatch
[] = {ISIS_NOTIFICATIONS
,
300 ISIS_TRAP_AREA_MISMATCH
};
301 static oid isis_snmp_trap_val_lsp_error
[] = {ISIS_NOTIFICATIONS
,
302 ISIS_TRAP_LSP_ERROR
};
305 * Trap vars under 'isisNotifications': note: we use full names of variables
308 static oid isis_snmp_trap_data_var_sys_level_index
[] = {
309 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_SYLELVELINDEX
, 0};
310 static oid isis_snmp_trap_data_var_circ_if_index
[] = {
311 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_CIRCIFINDEX
, 0};
312 static oid isis_snmp_trap_data_var_pdu_lsp_id
[] = {
313 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPID
, 0};
314 static oid isis_snmp_trap_data_var_pdu_fragment
[] = {
315 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FRAGMENT
, 0};
316 static oid isis_snmp_trap_data_var_pdu_field_len
[] = {
317 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FIELDLEN
, 0};
318 static oid isis_snmp_trap_data_var_pdu_max_area_addr
[] = {
319 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_MAXAREAADDR
, 0};
320 static oid isis_snmp_trap_data_var_pdu_proto_ver
[] = {
321 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_PROTOVER
, 0};
322 static oid isis_snmp_trap_data_var_pdu_lsp_size
[] = {
323 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPSIZE
, 0};
324 static oid isis_snmp_trap_data_var_adj_state
[] = {
325 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ADJ_STATE
, 0};
326 static oid isis_snmp_trap_data_var_error_offset
[] = {
327 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_OFFSET
, 0};
328 static oid isis_snmp_trap_data_var_error_tlv_type
[] = {
329 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_TLVTYPE
, 0};
332 * Other variables used by traps: note we use full names of variables and
333 * reserve space for index
335 static oid isis_snmp_trap_data_var_sys_level_state
[] = {
336 ISIS_MIB
, ISIS_SYSLEVEL_ENTRY
, ISIS_SYSLEVEL_STATE
, 0};
338 /* Throttle time values for traps */
339 static time_t isis_snmp_trap_timestamp
[ISIS_TRAP_LAST_TRAP
]; /* ?? 1 */
341 /* Max len of raw-pdu in traps */
342 #define ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN (64)
345 * Just to save on typing we have a shortcut structure
346 * to specify mib layout as prefix/leaf combination
348 #define ISIS_SNMP_PREF_LEN_MAX 10
349 struct isis_var_prefix
{
350 FindVarMethod
*findVar
;
351 uint8_t ivd_pref_len
;
352 oid ivd_pref
[ISIS_SNMP_PREF_LEN_MAX
];
356 /* Find-val functions */
357 static uint8_t *isis_snmp_find_sys_object(struct variable
*, oid
*, size_t *,
358 int, size_t *, WriteMethod
**);
360 static uint8_t *isis_snmp_find_man_area(struct variable
*, oid
*, size_t *, int,
361 size_t *, WriteMethod
**);
363 static uint8_t *isis_snmp_find_area_addr(struct variable
*, oid
*, size_t *,
364 int, size_t *, WriteMethod
**);
366 static uint8_t *isis_snmp_find_summ_addr(struct variable
*, oid
*, size_t *,
367 int, size_t *, WriteMethod
**);
369 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*, oid
*,
370 size_t *, int, size_t *,
373 static uint8_t *isis_snmp_find_router(struct variable
*, oid
*, size_t *, int,
374 size_t *, WriteMethod
**);
376 static uint8_t *isis_snmp_find_sys_level(struct variable
*, oid
*, size_t *,
377 int, size_t *, WriteMethod
**);
379 static uint8_t *isis_snmp_find_system_counter(struct variable
*, oid
*,
380 size_t *, int, size_t *,
383 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*, oid
*,
384 size_t *, int, size_t *,
387 static uint8_t *isis_snmp_find_circ(struct variable
*, oid
*, size_t *, int,
388 size_t *, WriteMethod
**);
390 static uint8_t *isis_snmp_find_circ_level(struct variable
*, oid
*, size_t *,
391 int, size_t *, WriteMethod
**);
393 static uint8_t *isis_snmp_find_circ_counter(struct variable
*, oid
*, size_t *,
394 int, size_t *, WriteMethod
**);
396 static uint8_t *isis_snmp_find_isadj(struct variable
*, oid
*, size_t *, int,
397 size_t *, WriteMethod
**);
399 static uint8_t *isis_snmp_find_isadj_area(struct variable
*, oid
*, size_t *,
400 int, size_t *, WriteMethod
**);
402 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*, oid
*, size_t *,
403 int, size_t *, WriteMethod
**);
405 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*, oid
*,
406 size_t *, int, size_t *,
410 * Just to save on typing we have a shortcut structure
411 * to specify mib layout, we populate the rest of the data
412 * during initialization
414 #define ISIS_PREF_LEN_MAX (6)
416 struct isis_func_to_prefix
{
417 FindVarMethod
*ihtp_func
;
418 oid ihtp_pref_oid
[ISIS_PREF_LEN_MAX
];
419 uint8_t ihtp_pref_len
;
422 static struct isis_func_to_prefix isis_func_to_prefix_arr
[] = {
423 {isis_snmp_find_sys_object
, {ISIS_SYS_OBJECT
}, 3},
424 {isis_snmp_find_man_area
, {ISIS_MANAREA_ADDRENTRY
}, 4},
425 {isis_snmp_find_area_addr
, {ISIS_AREA_ADDRENTRY
}, 4},
426 {isis_snmp_find_summ_addr
, {ISIS_SUMM_ADDRENTRY
}, 4},
427 {isis_snmp_find_redistribute_addr
, {ISIS_REDISTRIBUTE_ADDRENTRY
}, 4},
428 {isis_snmp_find_router
, {ISIS_ROUTER_ENTRY
}, 4},
429 {isis_snmp_find_sys_level
, {ISIS_SYSLEVEL_ENTRY
}, 4},
430 {isis_snmp_find_system_counter
, {ISIS_SYSTEM_COUNTER_ENTRY
}, 4},
431 {isis_snmp_find_next_circ_index
, {ISIS_CIRC
}, 2},
432 {isis_snmp_find_circ
, {ISIS_CIRC_ENTRY
}, 4},
433 {isis_snmp_find_circ_level
, {ISIS_CIRCLEVEL_ENTRY
}, 4},
434 {isis_snmp_find_circ_counter
, {ISIS_CIRC_COUNTER_ENTRY
}, 4},
435 {isis_snmp_find_isadj
, {ISIS_ISADJ_ENTRY
}, 4},
436 {isis_snmp_find_isadj_area
, {ISIS_ISADJAREA_ADDRENTRY
}, 4},
437 {isis_snmp_find_isadj_ipaddr
, {ISIS_ISADJIPADDR_ENTRY
}, 4},
438 {isis_snmp_find_isadj_prot_supp
, {ISIS_ISADJPROTSUPP_ENTRY
}, 4},
440 static size_t isis_func_to_prefix_count
= ARRAY_SIZE(isis_func_to_prefix_arr
);
442 static struct variable isis_var_arr
[] = {
443 {ISIS_SYS_VERSION
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
444 {ISIS_SYS_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
445 {ISIS_SYS_ID
, STRING
, RONLY
, isis_snmp_find_sys_object
},
446 {ISIS_SYS_MAXPATHSPLITS
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
447 {ISIS_SYS_MAXLSPGENINT
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
448 {ISIS_SYS_POLLESHELLORATE
, UNSIGNED32
, RONLY
,
449 isis_snmp_find_sys_object
},
450 {ISIS_SYS_WAITTIME
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
451 {ISIS_SYS_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
452 {ISIS_SYS_L2TOL1LEAKING
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
453 {ISIS_SYS_MAXAGE
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
454 {ISIS_SYS_RECEIVELSPBUFFERSIZE
, UNSIGNED32
, RONLY
,
455 isis_snmp_find_sys_object
},
456 {ISIS_SYS_PROTSUPPORTED
, STRING
, RONLY
, isis_snmp_find_sys_object
},
457 {ISIS_SYS_NOTIFICATIONENABLE
, INTEGER
, RONLY
,
458 isis_snmp_find_sys_object
},
459 {ISIS_MANAREA_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_man_area
},
460 {ISIS_AREA_ADDR
, STRING
, RONLY
, isis_snmp_find_area_addr
},
461 {ISIS_SUMM_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_summ_addr
},
462 {ISIS_SUMM_ADDRMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
463 {ISIS_SUMM_ADDRFULLMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
464 {ISIS_REDISTRIBUTE_ADDREXISTSTATE
, INTEGER
, RONLY
,
465 isis_snmp_find_redistribute_addr
},
466 {ISIS_ROUTER_HOSTNAME
, STRING
, RONLY
, isis_snmp_find_router
},
467 {ISIS_ROUTER_ID
, UNSIGNED32
, RONLY
, isis_snmp_find_router
},
468 {ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
, UNSIGNED32
, RONLY
,
469 isis_snmp_find_sys_level
},
470 {ISIS_SYSLEVEL_MINLSPGENINT
, UNSIGNED32
, RONLY
,
471 isis_snmp_find_sys_level
},
472 {ISIS_SYSLEVEL_STATE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
473 {ISIS_SYSLEVEL_SETOVERLOAD
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
474 {ISIS_SYSLEVEL_SETOVERLOADUNTIL
, UNSIGNED32
, RONLY
,
475 isis_snmp_find_sys_level
},
476 {ISIS_SYSLEVEL_METRICSTYLE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
477 {ISIS_SYSLEVEL_SPFCONSIDERS
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
478 {ISIS_SYSLEVEL_TEENABLED
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
479 {ISIS_SYSSTAT_CORRLSPS
, COUNTER32
, RONLY
,
480 isis_snmp_find_system_counter
},
481 {ISIS_SYSSTAT_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
482 isis_snmp_find_system_counter
},
483 {ISIS_SYSSTAT_AUTHFAILS
, COUNTER32
, RONLY
,
484 isis_snmp_find_system_counter
},
485 {ISIS_SYSSTAT_LSPDBASEOLOADS
, COUNTER32
, RONLY
,
486 isis_snmp_find_system_counter
},
487 {ISIS_SYSSTAT_MANADDRDROPFROMAREAS
, COUNTER32
, RONLY
,
488 isis_snmp_find_system_counter
},
489 {ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
, COUNTER32
, RONLY
,
490 isis_snmp_find_system_counter
},
491 {ISIS_SYSSTAT_SEQNUMSKIPS
, COUNTER32
, RONLY
,
492 isis_snmp_find_system_counter
},
493 {ISIS_SYSSTAT_OWNLSPPURGES
, COUNTER32
, RONLY
,
494 isis_snmp_find_system_counter
},
495 {ISIS_SYSSTAT_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
496 isis_snmp_find_system_counter
},
497 {ISIS_SYSSTAT_PARTCHANGES
, COUNTER32
, RONLY
,
498 isis_snmp_find_system_counter
},
499 {ISIS_SYSSTAT_SPFRUNS
, COUNTER32
, RONLY
, isis_snmp_find_system_counter
},
500 {ISIS_SYSSTAT_LSPERRORS
, COUNTER32
, RONLY
,
501 isis_snmp_find_system_counter
},
502 {ISIS_NEXTCIRC_INDEX
, UNSIGNED32
, RONLY
,
503 isis_snmp_find_next_circ_index
},
504 {ISIS_CIRC_IFINDEX
, INTEGER
, RONLY
, isis_snmp_find_circ
},
505 {ISIS_CIRC_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
506 {ISIS_CIRC_EXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
507 {ISIS_CIRC_TYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
508 {ISIS_CIRC_EXTDOMAIN
, INTEGER
, RONLY
, isis_snmp_find_circ
},
509 {ISIS_CIRC_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
510 {ISIS_CIRC_PASSIVECIRCUIT
, INTEGER
, RONLY
, isis_snmp_find_circ
},
511 {ISIS_CIRC_MESHGROUPENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
512 {ISIS_CIRC_MESHGROUP
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
513 {ISIS_CIRC_SMALLHELLOS
, INTEGER
, RONLY
, isis_snmp_find_circ
},
514 {ISIS_CIRC_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_circ
},
515 {ISIS_CIRC_3WAYENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
516 {ISIS_CIRC_EXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
517 {ISIS_CIRCLEVEL_METRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
518 {ISIS_CIRCLEVEL_WIDEMETRIC
, UNSIGNED32
, RONLY
,
519 isis_snmp_find_circ_level
},
520 {ISIS_CIRCLEVEL_ISPRIORITY
, UNSIGNED32
, RONLY
,
521 isis_snmp_find_circ_level
},
522 {ISIS_CIRCLEVEL_IDOCTET
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
523 {ISIS_CIRCLEVEL_ID
, STRING
, RONLY
, isis_snmp_find_circ_level
},
524 {ISIS_CIRCLEVEL_DESIS
, STRING
, RONLY
, isis_snmp_find_circ_level
},
525 {ISIS_CIRCLEVEL_HELLOMULTIPLIER
, UNSIGNED32
, RONLY
,
526 isis_snmp_find_circ_level
},
527 {ISIS_CIRCLEVEL_HELLOTIMER
, UNSIGNED32
, RONLY
,
528 isis_snmp_find_circ_level
},
529 {ISIS_CIRCLEVEL_DRHELLOTIMER
, UNSIGNED32
, RONLY
,
530 isis_snmp_find_circ_level
},
531 {ISIS_CIRCLEVEL_LSPTHROTTLE
, UNSIGNED32
, RONLY
,
532 isis_snmp_find_circ_level
},
533 {ISIS_CIRCLEVEL_MINLSPRETRANSINT
, UNSIGNED32
, RONLY
,
534 isis_snmp_find_circ_level
},
535 {ISIS_CIRCLEVEL_CSNPINTERVAL
, UNSIGNED32
, RONLY
,
536 isis_snmp_find_circ_level
},
537 {ISIS_CIRCLEVEL_PARTSNPINTERVAL
, UNSIGNED32
, RONLY
,
538 isis_snmp_find_circ_level
},
539 {ISIS_CIRC_ADJCHANGES
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
540 {ISIS_CIRC_NUMADJ
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_counter
},
541 {ISIS_CIRC_INITFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
542 {ISIS_CIRC_REJADJS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
543 {ISIS_CIRC_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
544 isis_snmp_find_circ_counter
},
545 {ISIS_CIRC_MAXAREAADDRMISMATCHES
, COUNTER32
, RONLY
,
546 isis_snmp_find_circ_counter
},
547 {ISIS_CIRC_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
548 isis_snmp_find_circ_counter
},
549 {ISIS_CIRC_AUTHFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
550 {ISIS_CIRC_LANDESISCHANGES
, COUNTER32
, RONLY
,
551 isis_snmp_find_circ_counter
},
552 {ISIS_ISADJ_STATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
553 {ISIS_ISADJ_3WAYSTATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
554 {ISIS_ISADJ_NEIGHSNPAADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj
},
555 {ISIS_ISADJ_NEIGHSYSTYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
556 {ISIS_ISADJ_NEIGHSYSID
, STRING
, RONLY
, isis_snmp_find_isadj
},
557 {ISIS_ISADJ_NBREXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
558 {ISIS_ISADJ_USAGE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
559 {ISIS_ISADJ_HOLDTIMER
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
560 {ISIS_ISADJ_NEIGHPRIORITY
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
561 {ISIS_ISADJ_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_isadj
},
562 {ISIS_ISADJAREA_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_area
},
563 {ISIS_ISADJIPADDR_TYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj_ipaddr
},
564 {ISIS_ISADJIPADDR_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_ipaddr
},
565 {ISIS_ISADJPROTSUPP_PROTOCOL
, INTEGER
, RONLY
,
566 isis_snmp_find_isadj_prot_supp
},
569 static const size_t isis_var_count
= ARRAY_SIZE(isis_var_arr
);
571 /* Minimal set of hard-coded data */
572 #define ISIS_VERSION (1)
574 /* If sys-id is not set use this value */
575 static uint8_t isis_null_sysid
[ISIS_SYS_ID_LEN
];
578 #define ISIS_SNMP_OSI_ADDR_LEN_MAX (20)
581 * The implementation has a fixed max-path splits value
582 * of 64 (see ISIS_MAX_PATH_SPLITS), the max mib value
585 * FIXME(aromanov): should we return 32 or 64?
587 #define ISIS_SNMP_MAX_PATH_SPLITS (32)
589 #define ISIS_SNMP_ADMIN_STATE_ON (1)
591 #define ISIS_SNMP_ROW_STATUS_ACTIVE (1)
593 #define ISIS_SNMP_LEVEL_STATE_OFF (1)
594 #define ISIS_SNMP_LEVEL_STATE_ON (2)
595 #define ISIS_SNMP_LEVEL_STATE_WAITING (3)
596 #define ISIS_SNMP_LEVEL_STATE_OVERLOADED (4)
598 #define ISIS_SNMP_TRUTH_VALUE_TRUE (1)
599 #define ISIS_SNMP_TRUTH_VALUE_FALSE (2)
601 #define ISIS_SNMP_METRIC_STYLE_NARROW (1)
602 #define ISIS_SNMP_METRIC_STYLE_WIDE (2)
603 #define ISIS_SNMP_METRIC_STYLE_BOTH (3)
605 #define ISIS_SNMP_MESH_GROUP_INACTIVE (1)
607 #define ISIS_SNMP_ADJ_STATE_DOWN (1)
608 #define ISIS_SNMP_ADJ_STATE_INITIALIZING (2)
609 #define ISIS_SNMP_ADJ_STATE_UP (3)
610 #define ISIS_SNMP_ADJ_STATE_FAILED (4)
612 static inline uint32_t isis_snmp_adj_state(enum isis_adj_state state
)
615 case ISIS_ADJ_UNKNOWN
:
616 return ISIS_SNMP_ADJ_STATE_DOWN
;
617 case ISIS_ADJ_INITIALIZING
:
618 return ISIS_SNMP_ADJ_STATE_INITIALIZING
;
620 return ISIS_SNMP_ADJ_STATE_UP
;
622 return ISIS_SNMP_ADJ_STATE_FAILED
;
625 return 0; /* not reached */
628 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1 (1)
629 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2 (2)
630 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2 (3)
631 #define ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN (4)
633 static inline uint32_t isis_snmp_adj_neightype(enum isis_system_type type
)
636 case ISIS_SYSTYPE_UNKNOWN
:
637 case ISIS_SYSTYPE_ES
:
638 return ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN
;
639 case ISIS_SYSTYPE_IS
:
640 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2
;
641 case ISIS_SYSTYPE_L1_IS
:
642 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1
;
643 case ISIS_SYSTYPE_L2_IS
:
644 return ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2
;
647 return 0; /* not reached */
650 #define ISIS_SNMP_INET_TYPE_V4 (1)
651 #define ISIS_SNMP_INET_TYPE_V6 (2)
653 #define ISIS_SNMP_P2P_CIRCUIT (3)
655 /* Protocols supported value */
656 static uint8_t isis_snmp_protocols_supported
= 0x7; /* All: iso, ipv4, ipv6 */
658 #define SNMP_CIRCUITS_MAX (512)
660 static struct isis_circuit
*snmp_circuits
[SNMP_CIRCUITS_MAX
];
661 static uint32_t snmp_circuit_id_last
;
663 static int isis_circuit_snmp_id_gen(struct isis_circuit
*circuit
)
668 id
= snmp_circuit_id_last
;
671 /* find next unused entry */
672 for (i
= 0; i
< SNMP_CIRCUITS_MAX
; i
++) {
673 if (id
>= SNMP_CIRCUITS_MAX
) {
681 if (snmp_circuits
[id
] == NULL
)
687 if (i
== SNMP_CIRCUITS_MAX
) {
688 zlog_warn("Could not allocate a smmp-circuit-id");
692 snmp_circuits
[id
] = circuit
;
693 snmp_circuit_id_last
= id
;
694 circuit
->snmp_id
= id
;
699 static int isis_circuit_snmp_id_free(struct isis_circuit
*circuit
)
701 snmp_circuits
[circuit
->snmp_id
] = NULL
;
702 circuit
->snmp_id
= 0;
707 * Convenience function to move to the next circuit,
709 static struct isis_circuit
*isis_snmp_circuit_next(struct isis_circuit
*circuit
)
717 start
= circuit
->snmp_id
+ 1;
719 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
720 circuit
= snmp_circuits
[off
];
730 * Convenience function to get the first matching level
732 static int isis_snmp_circuit_get_level_lo(struct isis_circuit
*circuit
)
734 if (circuit
->is_type
== IS_LEVEL_2
)
740 /* Check level match */
741 static int isis_snmp_get_level_match(int is_type
, int level
)
743 if (is_type
!= IS_LEVEL_1
&& is_type
!= IS_LEVEL_2
744 && is_type
!= IS_LEVEL_1_AND_2
)
747 if (level
!= IS_LEVEL_1
&& level
!= IS_LEVEL_2
)
751 if (is_type
== IS_LEVEL_1
) {
752 if (level
== IS_LEVEL_1
)
758 if (is_type
== IS_LEVEL_2
) {
759 if (level
== IS_LEVEL_2
)
768 * Helper function to convert oid index representing
769 * octet-string index (e.g. isis-sys-id) to byte string
770 * representing the same index.
772 * Also we do not fail if idx is longer than max_len,
773 * so we can use the same function to check compound
776 static int isis_snmp_conv_exact(uint8_t *buf
, size_t max_len
, size_t *out_len
,
777 const oid
*idx
, size_t idx_len
)
782 /* Oid representation: length followed by bytes */
783 if (idx
== NULL
|| idx_len
== 0)
791 if (idx_len
< len
+ 1)
794 for (off
= 0; off
< len
; off
++) {
795 if (idx
[off
+ 1] > 0xff)
798 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
806 static int isis_snmp_conv_next(uint8_t *buf
, size_t max_len
, size_t *out_len
,
807 int *try_exact
, const oid
*idx
, size_t idx_len
)
813 if (idx
== NULL
|| idx_len
== 0) {
826 if ((idx_len
- 1) < cmp_len
)
827 cmp_len
= idx_len
- 1;
829 for (off
= 0; off
< cmp_len
; off
++) {
830 if (idx
[off
+ 1] > 0xff) {
831 memset(buf
+ off
, 0xff, len
- off
);
837 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
841 memset(buf
+ cmp_len
, 0, len
- cmp_len
);
844 *try_exact
= cmp_len
< len
? 1 : 0;
849 * Helper functions to find area address from snmp index
851 static int isis_snmp_area_addr_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
852 struct isis_area
**ret_area
,
853 struct area_addr
**ret_addr
)
855 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
857 struct isis_area
*area
= NULL
;
858 struct area_addr
*addr
= NULL
;
859 struct listnode
*addr_node
;
860 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
865 if (list_isempty(isis
->area_list
)) {
866 /* Area is not configured yet */
870 area
= listgetdata(listhead(isis
->area_list
));
872 int res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
873 oid_idx
, oid_idx_len
);
876 if (!res
|| addr_len
== 0 || oid_idx_len
!= (addr_len
+ 1)) {
877 /* Bad conversion, empty address or extra oids at the end */
881 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
882 if (addr
->addr_len
!= addr_len
)
885 if (memcmp(addr
->area_addr
, cmp_buf
, addr_len
) == 0) {
898 static int isis_snmp_area_addr_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
899 struct isis_area
**ret_area
,
900 struct area_addr
**ret_addr
)
902 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
905 struct isis_area
*found_area
= NULL
;
906 struct isis_area
*area
= NULL
;
907 struct area_addr
*found_addr
= NULL
;
908 struct area_addr
*addr
= NULL
;
909 struct listnode
*addr_node
;
910 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
915 if (list_isempty(isis
->area_list
)) {
916 /* Area is not configured yet */
920 area
= listgetdata(listhead(isis
->area_list
));
922 int res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
923 &try_exact
, oid_idx
, oid_idx_len
);
928 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
929 if (addr
->addr_len
< addr_len
)
932 if (addr
->addr_len
== addr_len
) {
936 res
= memcmp(addr
->area_addr
, cmp_buf
, addr_len
);
941 if (res
== 0 && addr
->addr_len
== addr_len
) {
944 * This is the best match no point
955 if (found_addr
== NULL
|| addr
->addr_len
< found_addr
->addr_len
956 || (addr
->addr_len
== found_addr
->addr_len
957 && memcmp(addr
->area_addr
, found_addr
->area_addr
,
965 if (found_area
== NULL
)
969 *ret_area
= found_area
;
972 *ret_addr
= found_addr
;
978 * Helper functions to find circuit from
981 static int isis_snmp_circuit_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
982 struct isis_circuit
**ret_circuit
)
984 struct isis_circuit
*circuit
;
986 if (oid_idx
== NULL
|| oid_idx_len
< 1
987 || oid_idx
[0] > SNMP_CIRCUITS_MAX
)
990 circuit
= snmp_circuits
[oid_idx
[0]];
994 if (ret_circuit
!= NULL
)
995 *ret_circuit
= circuit
;
1000 static int isis_snmp_circuit_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
1001 struct isis_circuit
**ret_circuit
)
1005 struct isis_circuit
*circuit
;
1009 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
1010 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
1016 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; ++off
) {
1017 circuit
= snmp_circuits
[off
];
1019 if (circuit
!= NULL
&& off
> start
) {
1020 if (ret_circuit
!= NULL
)
1021 *ret_circuit
= circuit
;
1031 * Helper functions to find circuit level
1032 * combination from snmp index
1034 static int isis_snmp_circuit_level_lookup_exact(
1035 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
1036 struct isis_circuit
**ret_circuit
, int *ret_level
)
1040 struct isis_circuit
*circuit
;
1042 /* Minor optimization: check level first */
1043 if (oid_idx
== NULL
|| oid_idx_len
< 2)
1046 if (oid_idx
[1] < IS_LEVEL_1
|| oid_idx
[1] > IS_LEVEL_2
)
1049 level
= (int)oid_idx
[1];
1051 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1056 if (check_match
&& !isis_snmp_get_level_match(circuit
->is_type
, level
))
1059 if (ret_circuit
!= NULL
)
1060 *ret_circuit
= circuit
;
1062 if (ret_level
!= NULL
)
1068 static int isis_snmp_circuit_level_lookup_next(
1069 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
1070 struct isis_circuit
**ret_circuit
, int *ret_level
)
1074 struct isis_circuit
*circuit
= NULL
;
1079 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
1080 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
1086 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
1087 circuit
= snmp_circuits
[off
];
1089 if (circuit
== NULL
)
1092 if (off
> start
|| oid_idx_len
< 2) {
1093 /* Found and can use level 1 */
1098 assert(oid_idx
!= NULL
);
1100 /* We have to check level specified by index */
1101 if (oid_idx
[1] < IS_LEVEL_1
) {
1106 if (oid_idx
[1] < IS_LEVEL_2
) {
1115 if (circuit
== NULL
)
1119 && !isis_snmp_get_level_match(circuit
->is_type
, level
)) {
1120 if (level
== IS_LEVEL_1
) {
1122 * We can simply advance level because
1123 * at least one level should match
1127 /* We have to move to the next circuit */
1128 circuit
= isis_snmp_circuit_next(circuit
);
1129 if (circuit
== NULL
)
1132 level
= isis_snmp_circuit_get_level_lo(circuit
);
1136 if (ret_circuit
!= NULL
)
1137 *ret_circuit
= circuit
;
1139 if (ret_level
!= NULL
)
1146 * Helper functions to find adjacency
1149 * We have 4 tables related to adjacency
1150 * looking up adjacency is quite expensive
1151 * in case of bcast interfaces.
1153 * It is pain to have 4 very similar functions
1154 * hence we pass in and out additional data
1155 * we are looking for.
1157 * Note: we use data-len value to distinguish
1158 * between ipv4 and ipv6 addresses
1160 #define ISIS_SNMP_ADJ_DATA_NONE (1)
1161 #define ISIS_SNMP_ADJ_DATA_AREA_ADDR (2)
1162 #define ISIS_SNMP_ADJ_DATA_IP_ADDR (3)
1163 #define ISIS_SNMP_ADJ_DATA_PROTO (4)
1166 * Helper function to process data associated
1169 static int isis_snmp_adj_helper(struct isis_adjacency
*adj
, int data_id
,
1170 oid data_off
, uint8_t **ret_data
,
1171 size_t *ret_data_len
)
1173 uint8_t *data
= NULL
;
1174 size_t data_len
= 0;
1177 case ISIS_SNMP_ADJ_DATA_NONE
:
1180 case ISIS_SNMP_ADJ_DATA_AREA_ADDR
:
1181 if (data_off
>= adj
->area_address_count
)
1184 data
= adj
->area_addresses
[data_off
].area_addr
;
1185 data_len
= adj
->area_addresses
[data_off
].addr_len
;
1188 case ISIS_SNMP_ADJ_DATA_IP_ADDR
:
1189 if (data_off
>= (adj
->ipv4_address_count
+ adj
->ll_ipv6_count
))
1192 if (data_off
>= adj
->ipv4_address_count
) {
1193 data
= (uint8_t *)&adj
->ll_ipv6_addrs
1194 [data_off
- adj
->ipv4_address_count
];
1195 data_len
= sizeof(adj
->ll_ipv6_addrs
[0]);
1197 data
= (uint8_t *)&adj
->ipv4_addresses
[data_off
];
1198 data_len
= sizeof(adj
->ipv4_addresses
[0]);
1204 case ISIS_SNMP_ADJ_DATA_PROTO
:
1205 if (data_off
>= adj
->nlpids
.count
)
1208 data
= &adj
->nlpids
.nlpids
[data_off
];
1209 data_len
= sizeof(adj
->nlpids
.nlpids
[0]);
1217 if (ret_data
!= NULL
)
1220 if (ret_data_len
!= NULL
)
1221 *ret_data_len
= data_len
;
1226 static int isis_snmp_adj_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
1228 struct isis_adjacency
**ret_adj
,
1229 oid
*ret_data_idx
, uint8_t **ret_data
,
1230 size_t *ret_data_len
)
1233 struct listnode
*node
;
1234 struct isis_circuit
*circuit
;
1235 struct isis_adjacency
*adj
;
1236 struct isis_adjacency
*tmp_adj
;
1242 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1247 if (oid_idx
== NULL
|| oid_idx_len
< 2
1248 || (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
&& oid_idx_len
< 3))
1251 adj_idx
= oid_idx
[1];
1253 if (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
) {
1254 if (oid_idx
[2] == 0)
1257 data_off
= oid_idx
[2] - 1;
1260 * Data-off is not used if data-id is none
1261 * but we set it just for consistency
1270 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
, tmp_adj
)) {
1271 if (tmp_adj
->snmp_idx
> adj_idx
) {
1273 * Adjacencies are ordered in the list
1274 * no point to look further
1279 if (tmp_adj
->snmp_idx
== adj_idx
) {
1280 res
= isis_snmp_adj_helper(tmp_adj
, data_id
, data_off
,
1292 if (ret_adj
!= NULL
)
1295 if (ret_data_idx
!= NULL
)
1296 *ret_data_idx
= data_off
+ 1;
1302 *ret_data_len
= data_len
;
1307 static int isis_snmp_adj_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
1309 struct isis_adjacency
**ret_adj
,
1310 oid
*ret_data_idx
, uint8_t **ret_data
,
1311 size_t *ret_data_len
)
1313 struct listnode
*node
;
1314 struct isis_circuit
*circuit
;
1315 struct isis_adjacency
*adj
;
1316 struct isis_adjacency
*tmp_adj
;
1328 * Note: we rely on the fact that data indexes are consequtive
1332 if (oid_idx
== 0 || oid_idx_len
== 0) {
1336 } else if (oid_idx_len
== 1) {
1337 circ_idx
= oid_idx
[0];
1340 } else if (oid_idx_len
== 2) {
1341 circ_idx
= oid_idx
[0];
1342 adj_idx
= oid_idx
[1];
1345 circ_idx
= oid_idx
[0];
1346 adj_idx
= oid_idx
[1];
1348 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1351 data_idx
= oid_idx
[2];
1354 if (!isis_snmp_circuit_lookup_exact(&circ_idx
, 1, &circuit
)
1355 && !isis_snmp_circuit_lookup_next(&circ_idx
, 1, &circuit
))
1359 if (circuit
->snmp_id
!= circ_idx
) {
1360 /* Match is not exact */
1367 * Note: the simple loop below will work in all cases
1369 while (circuit
!= NULL
) {
1370 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
,
1372 if (tmp_adj
->snmp_idx
< adj_idx
)
1375 if (tmp_adj
->snmp_idx
== adj_idx
1376 && data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1379 if (adj_idx
!= 0 && tmp_adj
->snmp_idx
> adj_idx
)
1382 if (isis_snmp_adj_helper(tmp_adj
, data_id
, data_idx
,
1383 &data
, &data_len
)) {
1392 circuit
= isis_snmp_circuit_next(circuit
);
1401 if (ret_adj
!= NULL
)
1404 if (ret_data_idx
!= 0) {
1405 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1407 * Value does not matter but let us set
1408 * it to zero for consistency
1412 *ret_data_idx
= data_idx
+ 1;
1418 if (ret_data_len
!= 0)
1419 *ret_data_len
= data_len
;
1424 static uint8_t *isis_snmp_find_sys_object(struct variable
*v
, oid
*name
,
1425 size_t *length
, int exact
,
1427 WriteMethod
**write_method
)
1429 struct isis_area
*area
= NULL
;
1430 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1435 if (!list_isempty(isis
->area_list
))
1436 area
= listgetdata(listhead(isis
->area_list
));
1438 /* Check whether the instance identifier is valid */
1439 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
1444 case ISIS_SYS_VERSION
:
1445 return SNMP_INTEGER(ISIS_VERSION
);
1447 case ISIS_SYS_LEVELTYPE
:
1449 * If we do not have areas use 1&2 otherwise use settings
1450 * from the first area in the list
1453 return SNMP_INTEGER(IS_LEVEL_1_AND_2
);
1455 return SNMP_INTEGER(area
->is_type
);
1458 if (!isis
->sysid_set
) {
1459 *var_len
= ISIS_SYS_ID_LEN
;
1460 return isis_null_sysid
;
1463 *var_len
= ISIS_SYS_ID_LEN
;
1466 case ISIS_SYS_MAXPATHSPLITS
:
1467 return SNMP_INTEGER(ISIS_SNMP_MAX_PATH_SPLITS
);
1469 case ISIS_SYS_MAXLSPGENINT
:
1470 return SNMP_INTEGER(DEFAULT_MAX_LSP_GEN_INTERVAL
);
1472 case ISIS_SYS_POLLESHELLORATE
:
1473 return SNMP_INTEGER(DEFAULT_HELLO_INTERVAL
);
1475 case ISIS_SYS_WAITTIME
:
1476 /* Note: it seems that we have same fixed delay time */
1477 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1479 case ISIS_SYS_ADMINSTATE
:
1480 /* If daemon is running it admin state is on */
1481 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
1484 case ISIS_SYS_L2TOL1LEAKING
:
1485 /* We do not allow l2-to-l1 leaking */
1486 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1488 case ISIS_SYS_MAXAGE
:
1489 return SNMP_INTEGER(MAX_AGE
);
1491 case ISIS_SYS_RECEIVELSPBUFFERSIZE
:
1493 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1495 return SNMP_INTEGER(area
->lsp_mtu
);
1497 case ISIS_SYS_PROTSUPPORTED
:
1499 return &isis_snmp_protocols_supported
;
1501 case ISIS_SYS_NOTIFICATIONENABLE
:
1502 if (isis
->snmp_notifications
)
1503 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1505 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1515 static uint8_t *isis_snmp_find_man_area(struct variable
*v
, oid
*name
,
1516 size_t *length
, int exact
,
1518 WriteMethod
**write_method
)
1521 struct area_addr
*area_addr
= NULL
;
1526 *write_method
= NULL
;
1528 if (*length
<= v
->namelen
) {
1531 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1535 oid_idx
= name
+ v
->namelen
;
1536 oid_idx_len
= *length
- v
->namelen
;
1540 res
= isis_snmp_area_addr_lookup_exact(oid_idx
, oid_idx_len
,
1547 res
= isis_snmp_area_addr_lookup_next(oid_idx
, oid_idx_len
,
1553 /* Copy the name out */
1554 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1557 name
[v
->namelen
] = area_addr
->addr_len
;
1559 for (off
= 0; off
< area_addr
->addr_len
; off
++)
1560 name
[v
->namelen
+ 1 + off
] = area_addr
->area_addr
[off
];
1562 *length
= v
->namelen
+ 1 + area_addr
->addr_len
;
1566 case ISIS_MANAREA_ADDREXISTSTATE
:
1567 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
1576 static uint8_t *isis_snmp_find_area_addr(struct variable
*v
, oid
*name
,
1577 size_t *length
, int exact
,
1579 WriteMethod
**write_method
)
1582 * Area addresses in sense of addresses reported by L1 lsps
1583 * are not supported yet.
1592 *write_method
= NULL
;
1597 static uint8_t *isis_snmp_find_summ_addr(struct variable
*v
, oid
*name
,
1598 size_t *length
, int exact
,
1600 WriteMethod
**write_method
)
1603 * So far there is no way to set summary table values through cli
1604 * and snmp operations are read-only, hence there are no entries
1611 *write_method
= NULL
;
1616 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*v
, oid
*name
,
1617 size_t *length
, int exact
,
1619 WriteMethod
**write_method
)
1622 * It is not clear at the point whether redist code in isis is actually
1623 * used for now we will consider that entries are not present
1630 *write_method
= NULL
;
1635 static uint8_t *isis_snmp_find_router(struct variable
*v
, oid
*name
,
1636 size_t *length
, int exact
,
1638 WriteMethod
**write_method
)
1640 uint8_t cmp_buf
[ISIS_SYS_ID_LEN
];
1645 struct isis_dynhn
*dyn
= NULL
;
1649 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1654 *write_method
= NULL
;
1656 if (*length
<= v
->namelen
) {
1659 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1663 oid_idx
= name
+ v
->namelen
;
1664 oid_idx_len
= *length
- v
->namelen
;
1668 res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1669 oid_idx
, oid_idx_len
);
1671 if (!res
|| cmp_len
!= ISIS_SYS_ID_LEN
1672 || oid_idx_len
!= (cmp_len
+ 2))
1674 * Bad conversion, or bad length,
1675 * or extra oids at the end
1679 if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] < IS_LEVEL_1
1680 || oid_idx
[ISIS_SYS_ID_LEN
+ 1] > IS_LEVEL_2
)
1681 /* Level part of the index is out of range */
1684 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1686 dyn
= dynhn_find_by_id(isis
, cmp_buf
);
1688 if (dyn
== NULL
|| dyn
->level
!= cmp_level
)
1692 case ISIS_ROUTER_HOSTNAME
:
1693 *var_len
= strlen(dyn
->hostname
);
1694 return (uint8_t *)dyn
->hostname
;
1696 case ISIS_ROUTER_ID
:
1697 /* It seems that we do no know router-id in lsps */
1698 return SNMP_INTEGER(0);
1707 res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1708 &try_exact
, oid_idx
, oid_idx_len
);
1712 /* Bad conversion */
1715 if (cmp_len
!= ISIS_SYS_ID_LEN
) {
1716 /* We do not have valid index oids */
1717 memset(cmp_buf
, 0, sizeof(cmp_buf
));
1719 } else if (try_exact
)
1721 * We have no valid level index.
1722 * Let start from non-existing level 0 and
1723 * hence not need to do exact match
1726 else if (oid_idx_len
< (ISIS_SYS_ID_LEN
+ 2))
1728 else if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] <= IS_LEVEL_2
)
1729 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1732 * Any value greater than 2 will have the same result
1733 * but we can have integer overflows, hence 3 is a reasonable
1736 cmp_level
= (int)(IS_LEVEL_2
+ 1);
1738 dyn
= dynhn_snmp_next(isis
, cmp_buf
, cmp_level
);
1743 /* Copy the name out */
1744 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1747 name
[v
->namelen
] = ISIS_SYS_ID_LEN
;
1749 for (off
= 0; off
< ISIS_SYS_ID_LEN
; off
++)
1750 name
[v
->namelen
+ 1 + off
] = dyn
->id
[off
];
1752 name
[v
->namelen
+ 1 + ISIS_SYS_ID_LEN
] = (oid
)dyn
->level
;
1755 *length
= v
->namelen
+ 1 + ISIS_SYS_ID_LEN
+ 1;
1758 case ISIS_ROUTER_HOSTNAME
:
1759 *var_len
= strlen(dyn
->hostname
);
1760 return (uint8_t *)dyn
->hostname
;
1762 case ISIS_ROUTER_ID
:
1763 /* It seems that we do no know router-id in lsps */
1764 return SNMP_INTEGER(0);
1773 static uint8_t *isis_snmp_find_sys_level(struct variable
*v
, oid
*name
,
1774 size_t *length
, int exact
,
1776 WriteMethod
**write_method
)
1782 struct isis_area
*area
= NULL
;
1783 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1788 *write_method
= NULL
;
1790 if (*length
<= v
->namelen
) {
1793 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1797 oid_idx
= name
+ v
->namelen
;
1798 oid_idx_len
= *length
- v
->namelen
;
1802 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1805 if (oid_idx
[0] == IS_LEVEL_1
)
1807 else if (oid_idx
[0] == IS_LEVEL_2
)
1813 if (oid_idx
== NULL
)
1815 else if (oid_idx_len
== 0)
1817 else if (oid_idx
[0] < IS_LEVEL_1
)
1819 else if (oid_idx
[0] < IS_LEVEL_2
)
1824 /* Copy the name out */
1825 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1828 name
[v
->namelen
] = level
;
1831 *length
= v
->namelen
+ 1;
1836 if (!list_isempty(isis
->area_list
))
1837 area
= listgetdata(listhead(isis
->area_list
));
1842 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1845 case ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
:
1847 return SNMP_INTEGER(area
->lsp_mtu
);
1849 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1851 case ISIS_SYSLEVEL_MINLSPGENINT
:
1853 return SNMP_INTEGER(area
->lsp_gen_interval
[level
- 1]);
1855 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1857 case ISIS_SYSLEVEL_STATE
:
1859 if (area
->overload_bit
)
1860 return SNMP_INTEGER(
1861 ISIS_SNMP_LEVEL_STATE_OVERLOADED
);
1863 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_ON
);
1865 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_OFF
);
1867 case ISIS_SYSLEVEL_SETOVERLOAD
:
1868 if (level_match
&& area
->overload_bit
)
1869 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1871 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1873 case ISIS_SYSLEVEL_SETOVERLOADUNTIL
:
1874 /* We do not have automatic cleanup of overload bit */
1875 return SNMP_INTEGER(0);
1877 case ISIS_SYSLEVEL_METRICSTYLE
:
1879 if (area
->newmetric
&& area
->oldmetric
)
1880 return SNMP_INTEGER(
1881 ISIS_SNMP_METRIC_STYLE_BOTH
);
1883 if (area
->newmetric
)
1884 return SNMP_INTEGER(
1885 ISIS_SNMP_METRIC_STYLE_WIDE
);
1887 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1889 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1891 case ISIS_SYSLEVEL_SPFCONSIDERS
:
1892 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_BOTH
);
1894 case ISIS_SYSLEVEL_TEENABLED
:
1895 if (level_match
&& IS_MPLS_TE(area
->mta
))
1896 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1898 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1907 static uint8_t *isis_snmp_find_system_counter(struct variable
*v
, oid
*name
,
1908 size_t *length
, int exact
,
1910 WriteMethod
**write_method
)
1916 struct isis_area
*area
= NULL
;
1918 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1923 *write_method
= NULL
;
1925 if (*length
<= v
->namelen
) {
1928 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1932 oid_idx
= name
+ v
->namelen
;
1933 oid_idx_len
= *length
- v
->namelen
;
1937 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1940 if (oid_idx
[0] == IS_LEVEL_1
)
1942 else if (oid_idx
[0] == IS_LEVEL_2
)
1948 if (oid_idx
== NULL
)
1950 else if (oid_idx_len
== 0)
1952 else if (oid_idx
[0] < IS_LEVEL_1
)
1954 else if (oid_idx
[0] < IS_LEVEL_2
)
1959 /* Copy the name out */
1960 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1963 name
[v
->namelen
] = level
;
1966 *length
= v
->namelen
+ 1;
1971 if (!list_isempty(isis
->area_list
))
1972 area
= listgetdata(listhead(isis
->area_list
));
1977 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1980 /* If level does not match all counters are zeros */
1981 return SNMP_INTEGER(0);
1984 case ISIS_SYSSTAT_CORRLSPS
:
1988 case ISIS_SYSSTAT_AUTHTYPEFAILS
:
1989 val
= (uint32_t)area
->auth_type_failures
[level
- 1];
1992 case ISIS_SYSSTAT_AUTHFAILS
:
1993 val
= (uint32_t)area
->auth_failures
[level
- 1];
1996 case ISIS_SYSSTAT_LSPDBASEOLOADS
:
1997 val
= area
->overload_counter
;
2000 case ISIS_SYSSTAT_MANADDRDROPFROMAREAS
:
2001 /* We do not support manual addresses */
2005 case ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
:
2006 val
= area
->lsp_exceeded_max_counter
;
2009 case ISIS_SYSSTAT_SEQNUMSKIPS
:
2010 val
= area
->lsp_seqno_skipped_counter
;
2013 case ISIS_SYSSTAT_OWNLSPPURGES
:
2014 if (!area
->purge_originator
)
2017 val
= area
->lsp_purge_count
[level
- 1];
2020 case ISIS_SYSSTAT_IDFIELDLENMISMATCHES
:
2021 val
= (uint32_t)area
->id_len_mismatches
[level
- 1];
2024 case ISIS_SYSSTAT_PARTCHANGES
:
2029 case ISIS_SYSSTAT_SPFRUNS
:
2030 val
= (uint32_t)area
->spf_run_count
[level
- 1];
2033 case ISIS_SYSSTAT_LSPERRORS
:
2034 val
= (uint32_t)area
->lsp_error_counter
[level
- 1];
2041 return SNMP_INTEGER(val
);
2044 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*v
, oid
*name
,
2045 size_t *length
, int exact
,
2047 WriteMethod
**write_method
)
2049 /* Check whether the instance identifier is valid */
2050 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
2055 case ISIS_NEXTCIRC_INDEX
:
2057 * We do not support circuit creation through snmp
2059 return SNMP_INTEGER(0);
2068 static uint8_t *isis_snmp_find_circ(struct variable
*v
, oid
*name
,
2069 size_t *length
, int exact
, size_t *var_len
,
2070 WriteMethod
**write_method
)
2072 /* Index is circuit-id: 1-255 */
2075 struct isis_circuit
*circuit
;
2077 uint32_t delta_ticks
;
2081 *write_method
= NULL
;
2083 if (*length
<= v
->namelen
) {
2086 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2090 oid_idx
= name
+ v
->namelen
;
2091 oid_idx_len
= *length
- v
->namelen
;
2094 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
,
2097 if (!res
|| oid_idx_len
!= 1)
2101 res
= isis_snmp_circuit_lookup_next(oid_idx
, oid_idx_len
,
2107 /* Copy the name out */
2108 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2111 name
[v
->namelen
] = circuit
->snmp_id
;
2114 *length
= v
->namelen
+ 1;
2118 case ISIS_CIRC_IFINDEX
:
2119 if (circuit
->interface
== 0)
2120 return SNMP_INTEGER(0);
2122 return SNMP_INTEGER(circuit
->interface
->ifindex
);
2124 case ISIS_CIRC_ADMINSTATE
:
2125 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
2127 case ISIS_CIRC_EXISTSTATE
:
2128 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
2130 case ISIS_CIRC_TYPE
:
2132 * Note: values do not match 100%:
2134 * 1. From isis_circuit.h:
2135 * CIRCUIT_T_UNKNOWN 0
2136 * CIRCUIT_T_BROADCAST 1
2138 * CIRCUIT_T_LOOPBACK 3
2147 return SNMP_INTEGER(circuit
->circ_type
);
2149 case ISIS_CIRC_EXTDOMAIN
:
2150 if (circuit
->ext_domain
)
2151 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2153 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2155 case ISIS_CIRC_LEVELTYPE
:
2156 return SNMP_INTEGER(circuit
->is_type
);
2158 case ISIS_CIRC_PASSIVECIRCUIT
:
2159 if (circuit
->is_passive
)
2160 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2162 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2164 case ISIS_CIRC_MESHGROUPENABLED
:
2166 return SNMP_INTEGER(ISIS_SNMP_MESH_GROUP_INACTIVE
);
2168 case ISIS_CIRC_MESHGROUP
:
2170 return SNMP_INTEGER(0);
2172 case ISIS_CIRC_SMALLHELLOS
:
2174 * return false if lan hellos must be padded
2176 if (circuit
->pad_hellos
)
2177 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2179 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2181 case ISIS_CIRC_LASTUPTIME
:
2182 if (circuit
->last_uptime
== 0)
2183 return SNMP_INTEGER(0);
2185 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2186 now_time
= time(NULL
);
2188 if (circuit
->last_uptime
>= now_time
)
2189 return SNMP_INTEGER(up_ticks
);
2191 delta_ticks
= (now_time
- circuit
->last_uptime
) * 10;
2193 if (up_ticks
< delta_ticks
)
2194 return SNMP_INTEGER(up_ticks
);
2196 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2198 case ISIS_CIRC_3WAYENABLED
:
2200 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2202 case ISIS_CIRC_EXTENDEDCIRCID
:
2203 /* Used for 3-way hand shake only */
2204 return SNMP_INTEGER(0);
2213 static uint8_t *isis_snmp_find_circ_level(struct variable
*v
, oid
*name
,
2214 size_t *length
, int exact
,
2216 WriteMethod
**write_method
)
2218 static uint8_t circuit_id_val
[ISIS_SYS_ID_LEN
+ 1];
2219 /* Index is circuit-id: 1-255 + level: 1-2 */
2223 struct isis_circuit
*circuit
;
2225 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2230 *write_method
= NULL
;
2232 if (*length
<= v
->namelen
) {
2235 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2239 oid_idx
= name
+ v
->namelen
;
2240 oid_idx_len
= *length
- v
->namelen
;
2243 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2244 1, &circuit
, &level
);
2246 if (!res
|| oid_idx_len
!= 2)
2250 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2251 1, &circuit
, &level
);
2256 /* Copy the name out */
2257 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2260 name
[v
->namelen
] = circuit
->snmp_id
;
2261 name
[v
->namelen
+ 1] = level
;
2264 *length
= v
->namelen
+ 2;
2268 case ISIS_CIRCLEVEL_METRIC
:
2269 return SNMP_INTEGER(circuit
->metric
[level
- 1]);
2271 case ISIS_CIRCLEVEL_WIDEMETRIC
:
2272 if (circuit
->area
== NULL
|| !circuit
->area
->newmetric
) {
2273 /* What should we do if wide metric is not supported? */
2274 return SNMP_INTEGER(0);
2276 return SNMP_INTEGER(circuit
->te_metric
[level
- 1]);
2278 case ISIS_CIRCLEVEL_ISPRIORITY
:
2279 return SNMP_INTEGER(circuit
->priority
[level
- 1]);
2281 case ISIS_CIRCLEVEL_IDOCTET
:
2282 return SNMP_INTEGER(circuit
->circuit_id
);
2284 case ISIS_CIRCLEVEL_ID
:
2285 if (circuit
->circ_type
!= CIRCUIT_T_P2P
) {
2287 * Unless it is point-to-point circuit, the value is and
2288 * empty octet string
2291 return circuit_id_val
;
2294 /* !!!!!! Circuit-id is zero for p2p links */
2295 if (circuit
->u
.p2p
.neighbor
== NULL
2296 || circuit
->u
.p2p
.neighbor
->adj_state
!= ISIS_ADJ_UP
) {
2297 /* No adjacency or adjacency not fully up yet */
2298 memcpy(circuit_id_val
, isis
->sysid
, ISIS_SYS_ID_LEN
);
2299 circuit_id_val
[ISIS_SYS_ID_LEN
] = circuit
->circuit_id
;
2300 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2301 return circuit_id_val
;
2304 /* Adjacency fully-up */
2305 memcpy(circuit_id_val
, circuit
->u
.p2p
.neighbor
->sysid
,
2307 circuit_id_val
[ISIS_SYS_ID_LEN
] = 0;
2308 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2309 return circuit_id_val
;
2311 case ISIS_CIRCLEVEL_DESIS
:
2312 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
2313 || !circuit
->u
.bc
.is_dr
[level
- 1]) {
2315 * Unless it is lan circuit participating in dis process
2316 * the value is an empty octet string
2319 return circuit_id_val
;
2322 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2324 if (level
== IS_LEVEL_1
)
2325 return circuit
->u
.bc
.l1_desig_is
;
2327 return circuit
->u
.bc
.l2_desig_is
;
2329 case ISIS_CIRCLEVEL_HELLOMULTIPLIER
:
2330 return SNMP_INTEGER(circuit
->hello_multiplier
[level
- 1]);
2332 case ISIS_CIRCLEVEL_HELLOTIMER
:
2333 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2335 case ISIS_CIRCLEVEL_DRHELLOTIMER
:
2336 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2338 case ISIS_CIRCLEVEL_LSPTHROTTLE
:
2340 return SNMP_INTEGER(
2341 circuit
->area
->min_spf_interval
[level
- 1]
2344 return SNMP_INTEGER(0);
2346 case ISIS_CIRCLEVEL_MINLSPRETRANSINT
:
2348 return SNMP_INTEGER(
2349 circuit
->area
->min_spf_interval
[level
- 1]);
2351 return SNMP_INTEGER(0);
2353 case ISIS_CIRCLEVEL_CSNPINTERVAL
:
2354 return SNMP_INTEGER(circuit
->csnp_interval
[level
- 1]);
2356 case ISIS_CIRCLEVEL_PARTSNPINTERVAL
:
2357 return SNMP_INTEGER(circuit
->psnp_interval
[level
- 1]);
2366 static uint8_t *isis_snmp_find_circ_counter(struct variable
*v
, oid
*name
,
2367 size_t *length
, int exact
,
2369 WriteMethod
**write_method
)
2371 /* Index circuit-id 1-255 + level */
2375 struct isis_circuit
*circuit
;
2379 *write_method
= NULL
;
2381 if (*length
<= v
->namelen
) {
2384 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2388 oid_idx
= name
+ v
->namelen
;
2389 oid_idx_len
= *length
- v
->namelen
;
2392 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2393 1, &circuit
, &level
);
2395 if (!res
|| oid_idx_len
!= 2)
2399 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2400 1, &circuit
, &level
);
2405 /* Copy the name out */
2406 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2409 name
[v
->namelen
] = circuit
->snmp_id
;
2410 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2411 name
[v
->namelen
+ 1] = ISIS_SNMP_P2P_CIRCUIT
;
2413 name
[v
->namelen
+ 1] = level
;
2416 *length
= v
->namelen
+ 2;
2420 case ISIS_CIRC_ADJCHANGES
:
2421 val
= circuit
->adj_state_changes
;
2424 case ISIS_CIRC_NUMADJ
:
2425 if (circuit
->circ_type
== CIRCUIT_T_P2P
) {
2426 val
= circuit
->u
.p2p
.neighbor
== NULL
? 0 : 1;
2430 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
) {
2435 if (level
== IS_LEVEL_1
) {
2436 if (circuit
->u
.bc
.adjdb
[0] == NULL
)
2439 val
= listcount(circuit
->u
.bc
.adjdb
[0]);
2443 if (circuit
->u
.bc
.adjdb
[1] == NULL
)
2446 val
= listcount(circuit
->u
.bc
.adjdb
[1]);
2450 case ISIS_CIRC_INITFAILS
:
2451 val
= circuit
->init_failures
; /* counter never incremented */
2454 case ISIS_CIRC_REJADJS
:
2455 val
= circuit
->rej_adjacencies
;
2458 case ISIS_CIRC_IDFIELDLENMISMATCHES
:
2459 val
= circuit
->id_len_mismatches
;
2462 case ISIS_CIRC_MAXAREAADDRMISMATCHES
:
2463 val
= circuit
->max_area_addr_mismatches
;
2466 case ISIS_CIRC_AUTHTYPEFAILS
:
2467 val
= circuit
->auth_type_failures
;
2470 case ISIS_CIRC_AUTHFAILS
:
2471 val
= circuit
->auth_failures
;
2474 case ISIS_CIRC_LANDESISCHANGES
:
2475 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2478 val
= circuit
->desig_changes
[level
- 1];
2485 return SNMP_INTEGER(val
);
2488 static uint8_t *isis_snmp_find_isadj(struct variable
*v
, oid
*name
,
2489 size_t *length
, int exact
, size_t *var_len
,
2490 WriteMethod
**write_method
)
2492 /* Index is circuit-id: 1-255 + adj-id: 1-... */
2497 struct isis_adjacency
*adj
;
2499 uint32_t delta_ticks
;
2502 *write_method
= NULL
;
2504 if (*length
<= v
->namelen
) {
2507 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2511 oid_idx
= name
+ v
->namelen
;
2512 oid_idx_len
= *length
- v
->namelen
;
2515 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2516 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2519 if (!res
|| oid_idx_len
!= 2)
2523 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2524 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2529 /* Copy the name out */
2530 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2533 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2534 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2537 *length
= v
->namelen
+ 2;
2541 case ISIS_ISADJ_STATE
:
2542 return SNMP_INTEGER(isis_snmp_adj_state(adj
->adj_state
));
2544 case ISIS_ISADJ_3WAYSTATE
:
2545 return SNMP_INTEGER(adj
->threeway_state
);
2547 case ISIS_ISADJ_NEIGHSNPAADDRESS
: {
2548 const char *snpa
= (char *)snpa_print(adj
->snpa
);
2549 *var_len
= strlen(snpa
);
2550 return (uint8_t *)snpa
;
2553 case ISIS_ISADJ_NEIGHSYSTYPE
:
2554 return SNMP_INTEGER(isis_snmp_adj_neightype(adj
->sys_type
));
2556 case ISIS_ISADJ_NEIGHSYSID
:
2557 *var_len
= sizeof(adj
->sysid
);
2560 case ISIS_ISADJ_NBREXTENDEDCIRCID
:
2561 return SNMP_INTEGER(adj
->ext_circuit_id
!= 0 ? 1 : 0);
2563 case ISIS_ISADJ_USAGE
:
2564 /* It seems that no value conversion is required */
2565 return SNMP_INTEGER(adj
->adj_usage
);
2567 case ISIS_ISADJ_HOLDTIMER
:
2569 * It seems that we want remaining timer
2571 if (adj
->last_upd
!= 0) {
2573 if (val
< (adj
->last_upd
+ adj
->hold_time
))
2574 return SNMP_INTEGER(adj
->last_upd
2575 + adj
->hold_time
- val
);
2577 /* Not running or just expired */
2578 return SNMP_INTEGER(0);
2580 case ISIS_ISADJ_NEIGHPRIORITY
:
2581 return SNMP_INTEGER(adj
->prio
[adj
->level
- 1]);
2583 case ISIS_ISADJ_LASTUPTIME
:
2584 if (adj
->flaps
== 0)
2585 return SNMP_INTEGER(0);
2587 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2589 now_time
= time(NULL
);
2591 if (adj
->last_flap
>= now_time
)
2592 return SNMP_INTEGER(up_ticks
);
2594 delta_ticks
= (now_time
- adj
->last_flap
) * 10;
2596 if (up_ticks
< delta_ticks
)
2597 return SNMP_INTEGER(up_ticks
);
2599 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2608 static uint8_t *isis_snmp_find_isadj_area(struct variable
*v
, oid
*name
,
2609 size_t *length
, int exact
,
2611 WriteMethod
**write_method
)
2613 /* Index circuit-id: 1-255 + adj-id: 1-... */
2617 struct isis_adjacency
*adj
;
2622 *write_method
= NULL
;
2624 if (*length
<= v
->namelen
) {
2627 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2631 oid_idx
= name
+ v
->namelen
;
2632 oid_idx_len
= *length
- v
->namelen
;
2635 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2636 ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2637 &adj
, NULL
, &data
, &data_len
);
2639 if (!res
|| oid_idx_len
!= 3)
2643 res
= isis_snmp_adj_lookup_next(
2644 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2645 &adj
, &data_idx
, &data
, &data_len
);
2649 /* Copy the name out */
2650 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2653 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2654 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2655 name
[v
->namelen
+ 2] = data_idx
;
2658 *length
= v
->namelen
+ 3;
2662 case ISIS_ISADJAREA_ADDRESS
:
2663 *var_len
= data_len
;
2673 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*v
, oid
*name
,
2674 size_t *length
, int exact
,
2676 WriteMethod
**write_method
)
2678 /* Index circuit-id 1-255 + adj-id 1-... */
2682 struct isis_adjacency
*adj
;
2687 *write_method
= NULL
;
2689 if (*length
<= v
->namelen
) {
2692 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2696 oid_idx
= name
+ v
->namelen
;
2697 oid_idx_len
= *length
- v
->namelen
;
2700 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2701 ISIS_SNMP_ADJ_DATA_IP_ADDR
,
2702 &adj
, NULL
, &data
, &data_len
);
2704 if (!res
|| oid_idx_len
!= 3)
2707 res
= isis_snmp_adj_lookup_next(
2708 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_IP_ADDR
, &adj
,
2709 &data_idx
, &data
, &data_len
);
2713 /* Copy the name out */
2714 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2717 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2718 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2719 name
[v
->namelen
+ 2] = data_idx
;
2722 *length
= v
->namelen
+ 3;
2726 case ISIS_ISADJIPADDR_TYPE
:
2728 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V4
);
2730 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V6
);
2732 case ISIS_ISADJIPADDR_ADDRESS
:
2733 *var_len
= data_len
;
2743 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*v
, oid
*name
,
2744 size_t *length
, int exact
,
2746 WriteMethod
**write_method
)
2748 /* Index circuit-id 1-255 + adj-id 1-... */
2752 struct isis_adjacency
*adj
;
2757 *write_method
= NULL
;
2759 if (*length
<= v
->namelen
) {
2762 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2766 oid_idx
= name
+ v
->namelen
;
2767 oid_idx_len
= *length
- v
->namelen
;
2770 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2771 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2772 NULL
, &data
, &data_len
);
2774 if (!res
|| oid_idx_len
!= 3)
2778 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2779 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2780 &data_idx
, &data
, &data_len
);
2784 /* Copy the name out */
2785 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2788 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2789 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2790 name
[v
->namelen
+ 2] = data_idx
;
2793 *length
= v
->namelen
+ 3;
2797 case ISIS_ISADJPROTSUPP_PROTOCOL
:
2798 return SNMP_INTEGER(*data
);
2808 /* Register ISIS-MIB. */
2809 static int isis_snmp_init(struct thread_master
*tm
)
2811 struct isis_func_to_prefix
*h2f
= isis_func_to_prefix_arr
;
2814 for (size_t off
= 0; off
< isis_var_count
; off
++) {
2815 v
= &isis_var_arr
[off
];
2817 if (v
->findVar
!= h2f
->ihtp_func
) {
2820 assert(h2f
< (isis_func_to_prefix_arr
2821 + isis_func_to_prefix_count
));
2822 assert(v
->findVar
== h2f
->ihtp_func
);
2825 v
->namelen
= h2f
->ihtp_pref_len
+ 1;
2826 memcpy(v
->name
, h2f
->ihtp_pref_oid
,
2827 h2f
->ihtp_pref_len
* sizeof(oid
));
2828 v
->name
[h2f
->ihtp_pref_len
] = v
->magic
;
2833 REGISTER_MIB("mibII/isis", isis_var_arr
, variable
, isis_oid
);
2838 * ISIS notification functions: we have one function per notification
2840 static int isis_snmp_trap_throttle(oid trap_id
)
2843 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2845 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
2848 time_now
= time(NULL
);
2850 if ((isis_snmp_trap_timestamp
[trap_id
] + 5) > time_now
)
2851 /* Throttle trap rate at 1 in 5 secs */
2854 isis_snmp_trap_timestamp
[trap_id
] = time_now
;
2858 static int isis_snmp_db_overload_update(const struct isis_area
*area
)
2860 netsnmp_variable_list
*notification_vars
;
2864 if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD
))
2867 notification_vars
= NULL
;
2869 /* Put in trap value */
2870 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2871 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2872 (uint8_t *)&isis_snmp_trap_val_db_overload
,
2873 sizeof(isis_snmp_trap_val_db_overload
));
2876 val
= area
->is_type
;
2878 snmp_varlist_add_variable(
2879 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2880 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2881 (uint8_t *)&val
, sizeof(val
));
2883 /* Patch sys_level_state with proper index */
2884 off
= ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
) - 1;
2885 isis_snmp_trap_data_var_sys_level_state
[off
] = val
;
2888 if (area
->overload_bit
)
2889 val
= ISIS_SNMP_LEVEL_STATE_OVERLOADED
;
2891 val
= ISIS_SNMP_LEVEL_STATE_ON
;
2893 snmp_varlist_add_variable(
2894 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_state
,
2895 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
), INTEGER
,
2896 (uint8_t *)&val
, sizeof(val
));
2898 send_v2trap(notification_vars
);
2899 snmp_free_varbind(notification_vars
);
2900 smux_events_update();
2904 static int isis_snmp_lsp_exceed_max_update(const struct isis_area
*area
,
2905 const uint8_t *lsp_id
)
2907 netsnmp_variable_list
*notification_vars
;
2910 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_EXCEED_MAX
))
2913 notification_vars
= NULL
;
2915 /* Put in trap value */
2916 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2917 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2918 (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max
,
2919 sizeof(isis_snmp_trap_val_lsp_exceed_max
));
2922 val
= area
->is_type
;
2924 snmp_varlist_add_variable(
2925 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2926 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2927 (uint8_t *)&val
, sizeof(val
));
2929 snmp_varlist_add_variable(
2930 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
2931 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
2932 ISIS_SYS_ID_LEN
+ 2);
2934 send_v2trap(notification_vars
);
2935 snmp_free_varbind(notification_vars
);
2936 smux_events_update();
2942 * A common function to handle popular combination of trap objects
2943 * isisNotificationSysLevelIndex,
2945 * isisNotificationCircIfIndex,
2948 static void isis_snmp_update_worker_a(const struct isis_circuit
*circuit
,
2949 oid trap_id
, const oid
*oid_a
,
2950 size_t oid_a_len
, uint8_t type_a
,
2951 const void *data_a
, size_t data_a_len
,
2952 const oid
*oid_b
, size_t oid_b_len
,
2953 uint8_t type_b
, const void *data_b
,
2956 netsnmp_variable_list
*notification_vars
= NULL
;
2957 oid var_name
[MAX_OID_LEN
];
2962 if (trap_id
!= ISIS_TRAP_ID_LEN_MISMATCH
2963 && trap_id
!= ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
2964 && trap_id
!= ISIS_TRAP_OWN_LSP_PURGE
2965 && trap_id
!= ISIS_TRAP_SEQNO_SKIPPED
2966 && trap_id
!= ISIS_TRAP_AUTHEN_TYPE_FAILURE
2967 && trap_id
!= ISIS_TRAP_AUTHEN_FAILURE
2968 && trap_id
!= ISIS_TRAP_REJ_ADJACENCY
)
2971 /* Put in trap value */
2972 memcpy(var_name
, isis_snmp_notifications
,
2973 sizeof(isis_snmp_notifications
));
2974 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
2975 var_name
[var_count
++] = trap_id
;
2977 /* Put in trap value */
2978 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2979 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2980 (uint8_t *)var_name
, var_count
* sizeof(oid
));
2982 val
= circuit
->is_type
;
2983 snmp_varlist_add_variable(
2984 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2985 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2986 (uint8_t *)&val
, sizeof(val
));
2988 if (oid_a_len
!= 0) {
2989 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
2992 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
2993 type_a
, (uint8_t *)data_a
,
2997 if (circuit
->interface
== NULL
)
3000 val
= circuit
->interface
->ifindex
;
3002 snmp_varlist_add_variable(
3003 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3004 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3005 (uint8_t *)&val
, sizeof(val
));
3008 if (oid_b_len
!= 0) {
3009 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3012 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3013 type_b
, (uint8_t *)data_b
,
3017 send_v2trap(notification_vars
);
3018 snmp_free_varbind(notification_vars
);
3019 smux_events_update();
3023 * A common function to handle popular combination of trap objects
3024 * isisNotificationSysLevelIndex,
3025 * isisNotificationCircIfIndex,
3029 * Note: the only difference with worker_a is order of circ-if-index vs
3032 static void isis_snmp_update_worker_b(const struct isis_circuit
*circuit
,
3033 oid trap_id
, const oid
*oid_a
,
3034 size_t oid_a_len
, uint8_t type_a
,
3035 const void *data_a
, size_t data_a_len
,
3036 const oid
*oid_b
, size_t oid_b_len
,
3037 uint8_t type_b
, const void *data_b
,
3040 netsnmp_variable_list
*notification_vars
= NULL
;
3041 oid var_name
[MAX_OID_LEN
];
3046 if (trap_id
!= ISIS_TRAP_VERSION_SKEW
3047 && trap_id
!= ISIS_TRAP_LSP_TOO_LARGE
3048 && trap_id
!= ISIS_TRAP_ADJ_STATE_CHANGE
)
3051 /* Put in trap value */
3052 memcpy(var_name
, isis_snmp_notifications
,
3053 sizeof(isis_snmp_notifications
));
3054 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
3055 var_name
[var_count
++] = trap_id
;
3057 /* Put in trap value */
3058 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3059 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3060 (uint8_t *)var_name
, var_count
* sizeof(oid
));
3062 val
= circuit
->is_type
;
3063 snmp_varlist_add_variable(
3064 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3065 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3066 (uint8_t *)&val
, sizeof(val
));
3068 if (circuit
->interface
== NULL
)
3071 val
= circuit
->interface
->ifindex
;
3073 snmp_varlist_add_variable(
3074 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3075 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3076 (uint8_t *)&val
, sizeof(val
));
3079 if (oid_a_len
!= 0) {
3080 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
3083 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
3084 type_a
, (uint8_t *)data_a
,
3088 if (oid_b_len
!= 0) {
3089 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3092 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3093 type_b
, (uint8_t *)data_b
,
3097 send_v2trap(notification_vars
);
3098 snmp_free_varbind(notification_vars
);
3099 smux_events_update();
3103 static int isis_snmp_id_len_mismatch_update(const struct isis_circuit
*circuit
,
3104 uint8_t rcv_id
, const char *raw_pdu
,
3109 if (!isis_snmp_trap_throttle(ISIS_TRAP_ID_LEN_MISMATCH
))
3114 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3115 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3117 isis_snmp_update_worker_a(
3118 circuit
, ISIS_TRAP_ID_LEN_MISMATCH
,
3119 isis_snmp_trap_data_var_pdu_field_len
,
3120 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_field_len
), UNSIGNED32
,
3121 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3122 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3123 raw_pdu
, raw_pdu_len
);
3128 isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit
*circuit
,
3129 uint8_t max_addrs
, const char *raw_pdu
,
3134 if (!isis_snmp_trap_throttle(ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
))
3139 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3140 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3142 isis_snmp_update_worker_a(
3143 circuit
, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
,
3144 isis_snmp_trap_data_var_pdu_max_area_addr
,
3145 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_max_area_addr
),
3146 UNSIGNED32
, &val
, sizeof(val
),
3147 isis_snmp_trap_data_var_pdu_fragment
,
3148 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3149 raw_pdu
, raw_pdu_len
);
3153 static int isis_snmp_own_lsp_purge_update(const struct isis_circuit
*circuit
,
3154 const uint8_t *lsp_id
)
3156 if (!isis_snmp_trap_throttle(ISIS_TRAP_OWN_LSP_PURGE
))
3159 isis_snmp_update_worker_a(
3160 circuit
, ISIS_TRAP_OWN_LSP_PURGE
, 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);
3167 static int isis_snmp_seqno_skipped_update(const struct isis_circuit
*circuit
,
3168 const uint8_t *lsp_id
)
3170 if (!isis_snmp_trap_throttle(ISIS_TRAP_SEQNO_SKIPPED
))
3173 isis_snmp_update_worker_a(
3174 circuit
, ISIS_TRAP_SEQNO_SKIPPED
, NULL
, 0, STRING
, NULL
, 0,
3175 isis_snmp_trap_data_var_pdu_lsp_id
,
3176 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3177 ISIS_SYS_ID_LEN
+ 2);
3182 isis_snmp_authentication_type_failure_update(const struct isis_circuit
*circuit
,
3183 const char *raw_pdu
,
3186 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_TYPE_FAILURE
))
3189 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3190 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3192 isis_snmp_update_worker_a(
3193 circuit
, ISIS_TRAP_AUTHEN_TYPE_FAILURE
, NULL
, 0, STRING
, NULL
,
3194 0, isis_snmp_trap_data_var_pdu_fragment
,
3195 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3196 raw_pdu
, raw_pdu_len
);
3201 isis_snmp_authentication_failure_update(const struct isis_circuit
*circuit
,
3202 char const *raw_pdu
, size_t raw_pdu_len
)
3204 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_FAILURE
))
3207 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3208 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3210 isis_snmp_update_worker_a(
3211 circuit
, ISIS_TRAP_AUTHEN_FAILURE
, NULL
, 0, STRING
, NULL
, 0,
3212 isis_snmp_trap_data_var_pdu_fragment
,
3213 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3214 raw_pdu
, raw_pdu_len
);
3218 static int isis_snmp_version_skew_update(const struct isis_circuit
*circuit
,
3219 uint8_t version
, const char *raw_pdu
,
3224 if (!isis_snmp_trap_throttle(ISIS_TRAP_VERSION_SKEW
))
3229 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3230 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3232 isis_snmp_update_worker_b(
3233 circuit
, ISIS_TRAP_VERSION_SKEW
,
3234 isis_snmp_trap_data_var_pdu_proto_ver
,
3235 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_proto_ver
), UNSIGNED32
,
3236 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3237 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3238 raw_pdu
, raw_pdu_len
);
3242 static int isis_snmp_area_mismatch_update(const struct isis_circuit
*circuit
,
3243 const char *raw_pdu
,
3247 * This is a special case because
3248 * it does not include isisNotificationSysLevelIndex
3250 netsnmp_variable_list
*notification_vars
;
3253 if (!isis_snmp_trap_throttle(ISIS_TRAP_AREA_MISMATCH
))
3256 notification_vars
= NULL
;
3258 /* Put in trap value */
3259 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3260 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3261 (uint8_t *)&isis_snmp_trap_val_area_mismatch
,
3262 sizeof(isis_snmp_trap_val_area_mismatch
));
3265 if (circuit
->interface
== NULL
)
3268 val
= circuit
->interface
->ifindex
;
3270 snmp_varlist_add_variable(
3271 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3272 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3273 (uint8_t *)&val
, sizeof(val
));
3276 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3277 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3279 snmp_varlist_add_variable(
3280 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3281 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3282 raw_pdu
, raw_pdu_len
);
3284 send_v2trap(notification_vars
);
3285 snmp_free_varbind(notification_vars
);
3286 smux_events_update();
3291 static int isis_snmp_reject_adjacency_update(const struct isis_circuit
*circuit
,
3292 const char *raw_pdu
,
3295 if (!isis_snmp_trap_throttle(ISIS_TRAP_REJ_ADJACENCY
))
3298 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3299 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3301 isis_snmp_update_worker_a(
3302 circuit
, ISIS_TRAP_REJ_ADJACENCY
, NULL
, 0, STRING
, NULL
, 0,
3303 isis_snmp_trap_data_var_pdu_fragment
,
3304 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3305 raw_pdu
, raw_pdu_len
);
3309 static int isis_snmp_lsp_too_large_update(const struct isis_circuit
*circuit
,
3311 const uint8_t *lsp_id
)
3313 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_TOO_LARGE
))
3316 isis_snmp_update_worker_b(
3317 circuit
, ISIS_TRAP_LSP_TOO_LARGE
,
3318 isis_snmp_trap_data_var_pdu_lsp_size
,
3319 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_size
), UNSIGNED32
,
3320 &pdu_size
, sizeof(pdu_size
), isis_snmp_trap_data_var_pdu_lsp_id
,
3321 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3322 ISIS_SYS_ID_LEN
+ 2);
3327 static int isis_snmp_adj_state_change_update(const struct isis_adjacency
*adj
)
3329 uint8_t lsp_id
[ISIS_SYS_ID_LEN
+ 2];
3331 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
3333 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
3337 memcpy(lsp_id
, adj
->sysid
, ISIS_SYS_ID_LEN
);
3338 lsp_id
[ISIS_SYS_ID_LEN
] = 0;
3339 lsp_id
[ISIS_SYS_ID_LEN
+ 1] = 0;
3341 val
= isis_snmp_adj_state(adj
->adj_state
);
3343 isis_snmp_update_worker_b(
3344 adj
->circuit
, ISIS_TRAP_ADJ_STATE_CHANGE
,
3345 isis_snmp_trap_data_var_pdu_lsp_id
,
3346 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3347 ISIS_SYS_ID_LEN
+ 2, isis_snmp_trap_data_var_adj_state
,
3348 ARRAY_SIZE(isis_snmp_trap_data_var_adj_state
), INTEGER
, &val
,
3353 static int isis_snmp_lsp_error_update(const struct isis_circuit
*circuit
,
3354 const uint8_t *lsp_id
,
3355 char const *raw_pdu
, size_t raw_pdu_len
)
3358 * This is a special case because
3359 * it have more variables
3361 netsnmp_variable_list
*notification_vars
;
3364 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_ERROR
))
3367 notification_vars
= NULL
;
3369 /* Put in trap value */
3370 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3371 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3372 (uint8_t *)&isis_snmp_trap_val_lsp_error
,
3373 sizeof(isis_snmp_trap_val_lsp_error
));
3376 val
= circuit
->is_type
;
3378 snmp_varlist_add_variable(
3379 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3380 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3381 (uint8_t *)&val
, sizeof(val
));
3384 snmp_varlist_add_variable(
3385 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
3386 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3387 ISIS_SYS_ID_LEN
+ 2);
3390 if (circuit
->interface
== NULL
)
3393 val
= circuit
->interface
->ifindex
;
3395 snmp_varlist_add_variable(
3396 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3397 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3398 (uint8_t *)&val
, sizeof(val
));
3401 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3402 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3404 snmp_varlist_add_variable(
3405 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3406 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3407 raw_pdu
, raw_pdu_len
);
3412 snmp_varlist_add_variable(
3413 ¬ification_vars
, isis_snmp_trap_data_var_error_offset
,
3414 ARRAY_SIZE(isis_snmp_trap_data_var_error_offset
), UNSIGNED32
,
3415 (uint8_t *)&val
, sizeof(val
));
3420 snmp_varlist_add_variable(
3421 ¬ification_vars
, isis_snmp_trap_data_var_error_tlv_type
,
3422 ARRAY_SIZE(isis_snmp_trap_data_var_error_tlv_type
), UNSIGNED32
,
3423 (uint8_t *)&val
, sizeof(val
));
3425 send_v2trap(notification_vars
);
3426 snmp_free_varbind(notification_vars
);
3427 smux_events_update();
3432 static int isis_snmp_module_init(void)
3434 hook_register(isis_hook_db_overload
, isis_snmp_db_overload_update
);
3435 hook_register(isis_hook_lsp_exceed_max
,
3436 isis_snmp_lsp_exceed_max_update
);
3437 hook_register(isis_hook_id_len_mismatch
,
3438 isis_snmp_id_len_mismatch_update
);
3439 hook_register(isis_hook_max_area_addr_mismatch
,
3440 isis_snmp_max_area_addr_mismatch_update
);
3441 hook_register(isis_hook_own_lsp_purge
, isis_snmp_own_lsp_purge_update
);
3442 hook_register(isis_hook_seqno_skipped
, isis_snmp_seqno_skipped_update
);
3443 hook_register(isis_hook_authentication_type_failure
,
3444 isis_snmp_authentication_type_failure_update
);
3445 hook_register(isis_hook_authentication_failure
,
3446 isis_snmp_authentication_failure_update
);
3447 hook_register(isis_hook_version_skew
, isis_snmp_version_skew_update
);
3448 hook_register(isis_hook_area_mismatch
, isis_snmp_area_mismatch_update
);
3449 hook_register(isis_hook_reject_adjacency
,
3450 isis_snmp_reject_adjacency_update
);
3451 hook_register(isis_hook_lsp_too_large
, isis_snmp_lsp_too_large_update
);
3452 hook_register(isis_hook_adj_state_change
,
3453 isis_snmp_adj_state_change_update
);
3454 hook_register(isis_hook_lsp_error
, isis_snmp_lsp_error_update
);
3455 hook_register(isis_circuit_new_hook
, isis_circuit_snmp_id_gen
);
3456 hook_register(isis_circuit_del_hook
, isis_circuit_snmp_id_free
);
3458 hook_register(frr_late_init
, isis_snmp_init
);
3463 .name
= "isis_snmp",
3464 .version
= FRR_VERSION
,
3465 .description
= "isis AgentX SNMP module",
3466 .init
= isis_snmp_module_init
,