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
:
1190 >= (adj
->ipv4_address_count
+ adj
->ipv6_address_count
))
1193 if (data_off
>= adj
->ipv4_address_count
) {
1194 data
= (uint8_t *)&adj
->ipv6_addresses
1195 [data_off
- adj
->ipv4_address_count
];
1196 data_len
= sizeof(adj
->ipv6_addresses
[0]);
1198 data
= (uint8_t *)&adj
->ipv4_addresses
[data_off
];
1199 data_len
= sizeof(adj
->ipv4_addresses
[0]);
1205 case ISIS_SNMP_ADJ_DATA_PROTO
:
1206 if (data_off
>= adj
->nlpids
.count
)
1209 data
= &adj
->nlpids
.nlpids
[data_off
];
1210 data_len
= sizeof(adj
->nlpids
.nlpids
[0]);
1218 if (ret_data
!= NULL
)
1221 if (ret_data_len
!= NULL
)
1222 *ret_data_len
= data_len
;
1227 static int isis_snmp_adj_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
1229 struct isis_adjacency
**ret_adj
,
1230 oid
*ret_data_idx
, uint8_t **ret_data
,
1231 size_t *ret_data_len
)
1234 struct listnode
*node
;
1235 struct isis_circuit
*circuit
;
1236 struct isis_adjacency
*adj
;
1237 struct isis_adjacency
*tmp_adj
;
1243 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1248 if (oid_idx
== NULL
|| oid_idx_len
< 2
1249 || (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
&& oid_idx_len
< 3))
1252 adj_idx
= oid_idx
[1];
1254 if (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
) {
1255 if (oid_idx
[2] == 0)
1258 data_off
= oid_idx
[2] - 1;
1261 * Data-off is not used if data-id is none
1262 * but we set it just for consistency
1271 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
, tmp_adj
)) {
1272 if (tmp_adj
->snmp_idx
> adj_idx
) {
1274 * Adjacencies are ordered in the list
1275 * no point to look further
1280 if (tmp_adj
->snmp_idx
== adj_idx
) {
1281 res
= isis_snmp_adj_helper(tmp_adj
, data_id
, data_off
,
1293 if (ret_adj
!= NULL
)
1296 if (ret_data_idx
!= NULL
)
1297 *ret_data_idx
= data_off
+ 1;
1303 *ret_data_len
= data_len
;
1308 static int isis_snmp_adj_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
1310 struct isis_adjacency
**ret_adj
,
1311 oid
*ret_data_idx
, uint8_t **ret_data
,
1312 size_t *ret_data_len
)
1314 struct listnode
*node
;
1315 struct isis_circuit
*circuit
;
1316 struct isis_adjacency
*adj
;
1317 struct isis_adjacency
*tmp_adj
;
1329 * Note: we rely on the fact that data indexes are consequtive
1333 if (oid_idx
== 0 || oid_idx_len
== 0) {
1337 } else if (oid_idx_len
== 1) {
1338 circ_idx
= oid_idx
[0];
1341 } else if (oid_idx_len
== 2) {
1342 circ_idx
= oid_idx
[0];
1343 adj_idx
= oid_idx
[1];
1346 circ_idx
= oid_idx
[0];
1347 adj_idx
= oid_idx
[1];
1349 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1352 data_idx
= oid_idx
[2];
1355 if (!isis_snmp_circuit_lookup_exact(&circ_idx
, 1, &circuit
)
1356 && !isis_snmp_circuit_lookup_next(&circ_idx
, 1, &circuit
))
1360 if (circuit
->snmp_id
!= circ_idx
) {
1361 /* Match is not exact */
1368 * Note: the simple loop below will work in all cases
1370 while (circuit
!= NULL
) {
1371 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
,
1373 if (tmp_adj
->snmp_idx
< adj_idx
)
1376 if (tmp_adj
->snmp_idx
== adj_idx
1377 && data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1380 if (adj_idx
!= 0 && tmp_adj
->snmp_idx
> adj_idx
)
1383 if (isis_snmp_adj_helper(tmp_adj
, data_id
, data_idx
,
1384 &data
, &data_len
)) {
1393 circuit
= isis_snmp_circuit_next(circuit
);
1402 if (ret_adj
!= NULL
)
1405 if (ret_data_idx
!= 0) {
1406 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1408 * Value does not matter but let us set
1409 * it to zero for consistency
1413 *ret_data_idx
= data_idx
+ 1;
1419 if (ret_data_len
!= 0)
1420 *ret_data_len
= data_len
;
1425 static uint8_t *isis_snmp_find_sys_object(struct variable
*v
, oid
*name
,
1426 size_t *length
, int exact
,
1428 WriteMethod
**write_method
)
1430 struct isis_area
*area
= NULL
;
1431 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1436 if (!list_isempty(isis
->area_list
))
1437 area
= listgetdata(listhead(isis
->area_list
));
1439 /* Check whether the instance identifier is valid */
1440 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
1445 case ISIS_SYS_VERSION
:
1446 return SNMP_INTEGER(ISIS_VERSION
);
1448 case ISIS_SYS_LEVELTYPE
:
1450 * If we do not have areas use 1&2 otherwise use settings
1451 * from the first area in the list
1454 return SNMP_INTEGER(IS_LEVEL_1_AND_2
);
1456 return SNMP_INTEGER(area
->is_type
);
1459 if (!isis
->sysid_set
) {
1460 *var_len
= ISIS_SYS_ID_LEN
;
1461 return isis_null_sysid
;
1464 *var_len
= ISIS_SYS_ID_LEN
;
1467 case ISIS_SYS_MAXPATHSPLITS
:
1468 return SNMP_INTEGER(ISIS_SNMP_MAX_PATH_SPLITS
);
1470 case ISIS_SYS_MAXLSPGENINT
:
1471 return SNMP_INTEGER(DEFAULT_MAX_LSP_GEN_INTERVAL
);
1473 case ISIS_SYS_POLLESHELLORATE
:
1474 return SNMP_INTEGER(DEFAULT_HELLO_INTERVAL
);
1476 case ISIS_SYS_WAITTIME
:
1477 /* Note: it seems that we have same fixed delay time */
1478 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1480 case ISIS_SYS_ADMINSTATE
:
1481 /* If daemon is running it admin state is on */
1482 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
1485 case ISIS_SYS_L2TOL1LEAKING
:
1486 /* We do not allow l2-to-l1 leaking */
1487 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1489 case ISIS_SYS_MAXAGE
:
1490 return SNMP_INTEGER(MAX_AGE
);
1492 case ISIS_SYS_RECEIVELSPBUFFERSIZE
:
1494 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1496 return SNMP_INTEGER(area
->lsp_mtu
);
1498 case ISIS_SYS_PROTSUPPORTED
:
1500 return &isis_snmp_protocols_supported
;
1502 case ISIS_SYS_NOTIFICATIONENABLE
:
1503 if (isis
->snmp_notifications
)
1504 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1506 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1516 static uint8_t *isis_snmp_find_man_area(struct variable
*v
, oid
*name
,
1517 size_t *length
, int exact
,
1519 WriteMethod
**write_method
)
1522 struct area_addr
*area_addr
= NULL
;
1527 *write_method
= NULL
;
1529 if (*length
<= v
->namelen
) {
1532 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1536 oid_idx
= name
+ v
->namelen
;
1537 oid_idx_len
= *length
- v
->namelen
;
1541 res
= isis_snmp_area_addr_lookup_exact(oid_idx
, oid_idx_len
,
1548 res
= isis_snmp_area_addr_lookup_next(oid_idx
, oid_idx_len
,
1554 /* Copy the name out */
1555 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1558 name
[v
->namelen
] = area_addr
->addr_len
;
1560 for (off
= 0; off
< area_addr
->addr_len
; off
++)
1561 name
[v
->namelen
+ 1 + off
] = area_addr
->area_addr
[off
];
1563 *length
= v
->namelen
+ 1 + area_addr
->addr_len
;
1567 case ISIS_MANAREA_ADDREXISTSTATE
:
1568 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
1577 static uint8_t *isis_snmp_find_area_addr(struct variable
*v
, oid
*name
,
1578 size_t *length
, int exact
,
1580 WriteMethod
**write_method
)
1583 * Area addresses in sense of addresses reported by L1 lsps
1584 * are not supported yet.
1593 *write_method
= NULL
;
1598 static uint8_t *isis_snmp_find_summ_addr(struct variable
*v
, oid
*name
,
1599 size_t *length
, int exact
,
1601 WriteMethod
**write_method
)
1604 * So far there is no way to set summary table values through cli
1605 * and snmp operations are read-only, hence there are no entries
1612 *write_method
= NULL
;
1617 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*v
, oid
*name
,
1618 size_t *length
, int exact
,
1620 WriteMethod
**write_method
)
1623 * It is not clear at the point whether redist code in isis is actually
1624 * used for now we will consider that entries are not present
1631 *write_method
= NULL
;
1636 static uint8_t *isis_snmp_find_router(struct variable
*v
, oid
*name
,
1637 size_t *length
, int exact
,
1639 WriteMethod
**write_method
)
1641 uint8_t cmp_buf
[ISIS_SYS_ID_LEN
];
1646 struct isis_dynhn
*dyn
= NULL
;
1650 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1655 *write_method
= NULL
;
1657 if (*length
<= v
->namelen
) {
1660 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1664 oid_idx
= name
+ v
->namelen
;
1665 oid_idx_len
= *length
- v
->namelen
;
1669 res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1670 oid_idx
, oid_idx_len
);
1672 if (!res
|| cmp_len
!= ISIS_SYS_ID_LEN
1673 || oid_idx_len
!= (cmp_len
+ 2))
1675 * Bad conversion, or bad length,
1676 * or extra oids at the end
1680 if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] < IS_LEVEL_1
1681 || oid_idx
[ISIS_SYS_ID_LEN
+ 1] > IS_LEVEL_2
)
1682 /* Level part of the index is out of range */
1685 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1687 dyn
= dynhn_find_by_id(isis
, cmp_buf
);
1689 if (dyn
== NULL
|| dyn
->level
!= cmp_level
)
1693 case ISIS_ROUTER_HOSTNAME
:
1694 *var_len
= strlen(dyn
->hostname
);
1695 return (uint8_t *)dyn
->hostname
;
1697 case ISIS_ROUTER_ID
:
1698 /* It seems that we do no know router-id in lsps */
1699 return SNMP_INTEGER(0);
1708 res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1709 &try_exact
, oid_idx
, oid_idx_len
);
1713 /* Bad conversion */
1716 if (cmp_len
!= ISIS_SYS_ID_LEN
) {
1717 /* We do not have valid index oids */
1718 memset(cmp_buf
, 0, sizeof(cmp_buf
));
1720 } else if (try_exact
)
1722 * We have no valid level index.
1723 * Let start from non-existing level 0 and
1724 * hence not need to do exact match
1727 else if (oid_idx_len
< (ISIS_SYS_ID_LEN
+ 2))
1729 else if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] <= IS_LEVEL_2
)
1730 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1733 * Any value greater than 2 will have the same result
1734 * but we can have integer overflows, hence 3 is a reasonable
1737 cmp_level
= (int)(IS_LEVEL_2
+ 1);
1739 dyn
= dynhn_snmp_next(isis
, cmp_buf
, cmp_level
);
1744 /* Copy the name out */
1745 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1748 name
[v
->namelen
] = ISIS_SYS_ID_LEN
;
1750 for (off
= 0; off
< ISIS_SYS_ID_LEN
; off
++)
1751 name
[v
->namelen
+ 1 + off
] = dyn
->id
[off
];
1753 name
[v
->namelen
+ 1 + ISIS_SYS_ID_LEN
] = (oid
)dyn
->level
;
1756 *length
= v
->namelen
+ 1 + ISIS_SYS_ID_LEN
+ 1;
1759 case ISIS_ROUTER_HOSTNAME
:
1760 *var_len
= strlen(dyn
->hostname
);
1761 return (uint8_t *)dyn
->hostname
;
1763 case ISIS_ROUTER_ID
:
1764 /* It seems that we do no know router-id in lsps */
1765 return SNMP_INTEGER(0);
1774 static uint8_t *isis_snmp_find_sys_level(struct variable
*v
, oid
*name
,
1775 size_t *length
, int exact
,
1777 WriteMethod
**write_method
)
1783 struct isis_area
*area
= NULL
;
1784 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1789 *write_method
= NULL
;
1791 if (*length
<= v
->namelen
) {
1794 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1798 oid_idx
= name
+ v
->namelen
;
1799 oid_idx_len
= *length
- v
->namelen
;
1803 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1806 if (oid_idx
[0] == IS_LEVEL_1
)
1808 else if (oid_idx
[0] == IS_LEVEL_2
)
1814 if (oid_idx
== NULL
)
1816 else if (oid_idx_len
== 0)
1818 else if (oid_idx
[0] < IS_LEVEL_1
)
1820 else if (oid_idx
[0] < IS_LEVEL_2
)
1825 /* Copy the name out */
1826 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1829 name
[v
->namelen
] = level
;
1832 *length
= v
->namelen
+ 1;
1837 if (!list_isempty(isis
->area_list
))
1838 area
= listgetdata(listhead(isis
->area_list
));
1843 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1846 case ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
:
1848 return SNMP_INTEGER(area
->lsp_mtu
);
1850 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1852 case ISIS_SYSLEVEL_MINLSPGENINT
:
1854 return SNMP_INTEGER(area
->lsp_gen_interval
[level
- 1]);
1856 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1858 case ISIS_SYSLEVEL_STATE
:
1860 if (area
->overload_bit
)
1861 return SNMP_INTEGER(
1862 ISIS_SNMP_LEVEL_STATE_OVERLOADED
);
1864 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_ON
);
1866 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_OFF
);
1868 case ISIS_SYSLEVEL_SETOVERLOAD
:
1869 if (level_match
&& area
->overload_bit
)
1870 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1872 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1874 case ISIS_SYSLEVEL_SETOVERLOADUNTIL
:
1875 /* We do not have automatic cleanup of overload bit */
1876 return SNMP_INTEGER(0);
1878 case ISIS_SYSLEVEL_METRICSTYLE
:
1880 if (area
->newmetric
&& area
->oldmetric
)
1881 return SNMP_INTEGER(
1882 ISIS_SNMP_METRIC_STYLE_BOTH
);
1884 if (area
->newmetric
)
1885 return SNMP_INTEGER(
1886 ISIS_SNMP_METRIC_STYLE_WIDE
);
1888 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1890 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1892 case ISIS_SYSLEVEL_SPFCONSIDERS
:
1893 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_BOTH
);
1895 case ISIS_SYSLEVEL_TEENABLED
:
1896 if (level_match
&& IS_MPLS_TE(area
->mta
))
1897 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1899 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1908 static uint8_t *isis_snmp_find_system_counter(struct variable
*v
, oid
*name
,
1909 size_t *length
, int exact
,
1911 WriteMethod
**write_method
)
1917 struct isis_area
*area
= NULL
;
1919 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1924 *write_method
= NULL
;
1926 if (*length
<= v
->namelen
) {
1929 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1933 oid_idx
= name
+ v
->namelen
;
1934 oid_idx_len
= *length
- v
->namelen
;
1938 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1941 if (oid_idx
[0] == IS_LEVEL_1
)
1943 else if (oid_idx
[0] == IS_LEVEL_2
)
1949 if (oid_idx
== NULL
)
1951 else if (oid_idx_len
== 0)
1953 else if (oid_idx
[0] < IS_LEVEL_1
)
1955 else if (oid_idx
[0] < IS_LEVEL_2
)
1960 /* Copy the name out */
1961 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1964 name
[v
->namelen
] = level
;
1967 *length
= v
->namelen
+ 1;
1972 if (!list_isempty(isis
->area_list
))
1973 area
= listgetdata(listhead(isis
->area_list
));
1978 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1981 /* If level does not match all counters are zeros */
1982 return SNMP_INTEGER(0);
1985 case ISIS_SYSSTAT_CORRLSPS
:
1989 case ISIS_SYSSTAT_AUTHTYPEFAILS
:
1990 val
= (uint32_t)area
->auth_type_failures
[level
- 1];
1993 case ISIS_SYSSTAT_AUTHFAILS
:
1994 val
= (uint32_t)area
->auth_failures
[level
- 1];
1997 case ISIS_SYSSTAT_LSPDBASEOLOADS
:
1998 val
= area
->overload_counter
;
2001 case ISIS_SYSSTAT_MANADDRDROPFROMAREAS
:
2002 /* We do not support manual addresses */
2006 case ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
:
2007 val
= area
->lsp_exceeded_max_counter
;
2010 case ISIS_SYSSTAT_SEQNUMSKIPS
:
2011 val
= area
->lsp_seqno_skipped_counter
;
2014 case ISIS_SYSSTAT_OWNLSPPURGES
:
2015 if (!area
->purge_originator
)
2018 val
= area
->lsp_purge_count
[level
- 1];
2021 case ISIS_SYSSTAT_IDFIELDLENMISMATCHES
:
2022 val
= (uint32_t)area
->id_len_mismatches
[level
- 1];
2025 case ISIS_SYSSTAT_PARTCHANGES
:
2030 case ISIS_SYSSTAT_SPFRUNS
:
2031 val
= (uint32_t)area
->spf_run_count
[level
- 1];
2034 case ISIS_SYSSTAT_LSPERRORS
:
2035 val
= (uint32_t)area
->lsp_error_counter
[level
- 1];
2042 return SNMP_INTEGER(val
);
2045 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*v
, oid
*name
,
2046 size_t *length
, int exact
,
2048 WriteMethod
**write_method
)
2050 /* Check whether the instance identifier is valid */
2051 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
2056 case ISIS_NEXTCIRC_INDEX
:
2058 * We do not support circuit creation through snmp
2060 return SNMP_INTEGER(0);
2069 static uint8_t *isis_snmp_find_circ(struct variable
*v
, oid
*name
,
2070 size_t *length
, int exact
, size_t *var_len
,
2071 WriteMethod
**write_method
)
2073 /* Index is circuit-id: 1-255 */
2076 struct isis_circuit
*circuit
;
2078 uint32_t delta_ticks
;
2082 *write_method
= NULL
;
2084 if (*length
<= v
->namelen
) {
2087 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2091 oid_idx
= name
+ v
->namelen
;
2092 oid_idx_len
= *length
- v
->namelen
;
2095 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
,
2098 if (!res
|| oid_idx_len
!= 1)
2102 res
= isis_snmp_circuit_lookup_next(oid_idx
, oid_idx_len
,
2108 /* Copy the name out */
2109 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2112 name
[v
->namelen
] = circuit
->snmp_id
;
2115 *length
= v
->namelen
+ 1;
2119 case ISIS_CIRC_IFINDEX
:
2120 if (circuit
->interface
== 0)
2121 return SNMP_INTEGER(0);
2123 return SNMP_INTEGER(circuit
->interface
->ifindex
);
2125 case ISIS_CIRC_ADMINSTATE
:
2126 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
2128 case ISIS_CIRC_EXISTSTATE
:
2129 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
2131 case ISIS_CIRC_TYPE
:
2133 * Note: values do not match 100%:
2135 * 1. From isis_circuit.h:
2136 * CIRCUIT_T_UNKNOWN 0
2137 * CIRCUIT_T_BROADCAST 1
2139 * CIRCUIT_T_LOOPBACK 3
2148 return SNMP_INTEGER(circuit
->circ_type
);
2150 case ISIS_CIRC_EXTDOMAIN
:
2151 if (circuit
->ext_domain
)
2152 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2154 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2156 case ISIS_CIRC_LEVELTYPE
:
2157 return SNMP_INTEGER(circuit
->is_type
);
2159 case ISIS_CIRC_PASSIVECIRCUIT
:
2160 if (circuit
->is_passive
)
2161 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2163 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2165 case ISIS_CIRC_MESHGROUPENABLED
:
2167 return SNMP_INTEGER(ISIS_SNMP_MESH_GROUP_INACTIVE
);
2169 case ISIS_CIRC_MESHGROUP
:
2171 return SNMP_INTEGER(0);
2173 case ISIS_CIRC_SMALLHELLOS
:
2175 * return false if lan hellos must be padded
2177 if (circuit
->pad_hellos
)
2178 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2180 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2182 case ISIS_CIRC_LASTUPTIME
:
2183 if (circuit
->last_uptime
== 0)
2184 return SNMP_INTEGER(0);
2186 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2187 now_time
= time(NULL
);
2189 if (circuit
->last_uptime
>= now_time
)
2190 return SNMP_INTEGER(up_ticks
);
2192 delta_ticks
= (now_time
- circuit
->last_uptime
) * 10;
2194 if (up_ticks
< delta_ticks
)
2195 return SNMP_INTEGER(up_ticks
);
2197 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2199 case ISIS_CIRC_3WAYENABLED
:
2201 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2203 case ISIS_CIRC_EXTENDEDCIRCID
:
2204 /* Used for 3-way hand shake only */
2205 return SNMP_INTEGER(0);
2214 static uint8_t *isis_snmp_find_circ_level(struct variable
*v
, oid
*name
,
2215 size_t *length
, int exact
,
2217 WriteMethod
**write_method
)
2219 static uint8_t circuit_id_val
[ISIS_SYS_ID_LEN
+ 1];
2220 /* Index is circuit-id: 1-255 + level: 1-2 */
2224 struct isis_circuit
*circuit
;
2226 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2231 *write_method
= NULL
;
2233 if (*length
<= v
->namelen
) {
2236 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2240 oid_idx
= name
+ v
->namelen
;
2241 oid_idx_len
= *length
- v
->namelen
;
2244 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2245 1, &circuit
, &level
);
2247 if (!res
|| oid_idx_len
!= 2)
2251 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2252 1, &circuit
, &level
);
2257 /* Copy the name out */
2258 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2261 name
[v
->namelen
] = circuit
->snmp_id
;
2262 name
[v
->namelen
+ 1] = level
;
2265 *length
= v
->namelen
+ 2;
2269 case ISIS_CIRCLEVEL_METRIC
:
2270 return SNMP_INTEGER(circuit
->metric
[level
- 1]);
2272 case ISIS_CIRCLEVEL_WIDEMETRIC
:
2273 if (circuit
->area
== NULL
|| !circuit
->area
->newmetric
) {
2274 /* What should we do if wide metric is not supported? */
2275 return SNMP_INTEGER(0);
2277 return SNMP_INTEGER(circuit
->te_metric
[level
- 1]);
2279 case ISIS_CIRCLEVEL_ISPRIORITY
:
2280 return SNMP_INTEGER(circuit
->priority
[level
- 1]);
2282 case ISIS_CIRCLEVEL_IDOCTET
:
2283 return SNMP_INTEGER(circuit
->circuit_id
);
2285 case ISIS_CIRCLEVEL_ID
:
2286 if (circuit
->circ_type
!= CIRCUIT_T_P2P
) {
2288 * Unless it is point-to-point circuit, the value is and
2289 * empty octet string
2292 return circuit_id_val
;
2295 /* !!!!!! Circuit-id is zero for p2p links */
2296 if (circuit
->u
.p2p
.neighbor
== NULL
2297 || circuit
->u
.p2p
.neighbor
->adj_state
!= ISIS_ADJ_UP
) {
2298 /* No adjacency or adjacency not fully up yet */
2299 memcpy(circuit_id_val
, isis
->sysid
, ISIS_SYS_ID_LEN
);
2300 circuit_id_val
[ISIS_SYS_ID_LEN
] = circuit
->circuit_id
;
2301 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2302 return circuit_id_val
;
2305 /* Adjacency fully-up */
2306 memcpy(circuit_id_val
, circuit
->u
.p2p
.neighbor
->sysid
,
2308 circuit_id_val
[ISIS_SYS_ID_LEN
] = 0;
2309 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2310 return circuit_id_val
;
2312 case ISIS_CIRCLEVEL_DESIS
:
2313 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
2314 || !circuit
->u
.bc
.is_dr
[level
- 1]) {
2316 * Unless it is lan circuit participating in dis process
2317 * the value is an empty octet string
2320 return circuit_id_val
;
2323 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2325 if (level
== IS_LEVEL_1
)
2326 return circuit
->u
.bc
.l1_desig_is
;
2328 return circuit
->u
.bc
.l2_desig_is
;
2330 case ISIS_CIRCLEVEL_HELLOMULTIPLIER
:
2331 return SNMP_INTEGER(circuit
->hello_multiplier
[level
- 1]);
2333 case ISIS_CIRCLEVEL_HELLOTIMER
:
2334 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2336 case ISIS_CIRCLEVEL_DRHELLOTIMER
:
2337 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2339 case ISIS_CIRCLEVEL_LSPTHROTTLE
:
2341 return SNMP_INTEGER(
2342 circuit
->area
->min_spf_interval
[level
- 1]
2345 return SNMP_INTEGER(0);
2347 case ISIS_CIRCLEVEL_MINLSPRETRANSINT
:
2349 return SNMP_INTEGER(
2350 circuit
->area
->min_spf_interval
[level
- 1]);
2352 return SNMP_INTEGER(0);
2354 case ISIS_CIRCLEVEL_CSNPINTERVAL
:
2355 return SNMP_INTEGER(circuit
->csnp_interval
[level
- 1]);
2357 case ISIS_CIRCLEVEL_PARTSNPINTERVAL
:
2358 return SNMP_INTEGER(circuit
->psnp_interval
[level
- 1]);
2367 static uint8_t *isis_snmp_find_circ_counter(struct variable
*v
, oid
*name
,
2368 size_t *length
, int exact
,
2370 WriteMethod
**write_method
)
2372 /* Index circuit-id 1-255 + level */
2376 struct isis_circuit
*circuit
;
2380 *write_method
= NULL
;
2382 if (*length
<= v
->namelen
) {
2385 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2389 oid_idx
= name
+ v
->namelen
;
2390 oid_idx_len
= *length
- v
->namelen
;
2393 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2394 1, &circuit
, &level
);
2396 if (!res
|| oid_idx_len
!= 2)
2400 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2401 1, &circuit
, &level
);
2406 /* Copy the name out */
2407 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2410 name
[v
->namelen
] = circuit
->snmp_id
;
2411 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2412 name
[v
->namelen
+ 1] = ISIS_SNMP_P2P_CIRCUIT
;
2414 name
[v
->namelen
+ 1] = level
;
2417 *length
= v
->namelen
+ 2;
2421 case ISIS_CIRC_ADJCHANGES
:
2422 val
= circuit
->adj_state_changes
;
2425 case ISIS_CIRC_NUMADJ
:
2426 if (circuit
->circ_type
== CIRCUIT_T_P2P
) {
2427 val
= circuit
->u
.p2p
.neighbor
== NULL
? 0 : 1;
2431 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
) {
2436 if (level
== IS_LEVEL_1
) {
2437 if (circuit
->u
.bc
.adjdb
[0] == NULL
)
2440 val
= listcount(circuit
->u
.bc
.adjdb
[0]);
2444 if (circuit
->u
.bc
.adjdb
[1] == NULL
)
2447 val
= listcount(circuit
->u
.bc
.adjdb
[1]);
2451 case ISIS_CIRC_INITFAILS
:
2452 val
= circuit
->init_failures
; /* counter never incremented */
2455 case ISIS_CIRC_REJADJS
:
2456 val
= circuit
->rej_adjacencies
;
2459 case ISIS_CIRC_IDFIELDLENMISMATCHES
:
2460 val
= circuit
->id_len_mismatches
;
2463 case ISIS_CIRC_MAXAREAADDRMISMATCHES
:
2464 val
= circuit
->max_area_addr_mismatches
;
2467 case ISIS_CIRC_AUTHTYPEFAILS
:
2468 val
= circuit
->auth_type_failures
;
2471 case ISIS_CIRC_AUTHFAILS
:
2472 val
= circuit
->auth_failures
;
2475 case ISIS_CIRC_LANDESISCHANGES
:
2476 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2479 val
= circuit
->desig_changes
[level
- 1];
2486 return SNMP_INTEGER(val
);
2489 static uint8_t *isis_snmp_find_isadj(struct variable
*v
, oid
*name
,
2490 size_t *length
, int exact
, size_t *var_len
,
2491 WriteMethod
**write_method
)
2493 /* Index is circuit-id: 1-255 + adj-id: 1-... */
2498 struct isis_adjacency
*adj
;
2500 uint32_t delta_ticks
;
2503 *write_method
= NULL
;
2505 if (*length
<= v
->namelen
) {
2508 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2512 oid_idx
= name
+ v
->namelen
;
2513 oid_idx_len
= *length
- v
->namelen
;
2516 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2517 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2520 if (!res
|| oid_idx_len
!= 2)
2524 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2525 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2530 /* Copy the name out */
2531 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2534 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2535 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2538 *length
= v
->namelen
+ 2;
2542 case ISIS_ISADJ_STATE
:
2543 return SNMP_INTEGER(isis_snmp_adj_state(adj
->adj_state
));
2545 case ISIS_ISADJ_3WAYSTATE
:
2546 return SNMP_INTEGER(adj
->threeway_state
);
2548 case ISIS_ISADJ_NEIGHSNPAADDRESS
: {
2549 const char *snpa
= (char *)snpa_print(adj
->snpa
);
2550 *var_len
= strlen(snpa
);
2551 return (uint8_t *)snpa
;
2554 case ISIS_ISADJ_NEIGHSYSTYPE
:
2555 return SNMP_INTEGER(isis_snmp_adj_neightype(adj
->sys_type
));
2557 case ISIS_ISADJ_NEIGHSYSID
:
2558 *var_len
= sizeof(adj
->sysid
);
2561 case ISIS_ISADJ_NBREXTENDEDCIRCID
:
2562 return SNMP_INTEGER(adj
->ext_circuit_id
!= 0 ? 1 : 0);
2564 case ISIS_ISADJ_USAGE
:
2565 /* It seems that no value conversion is required */
2566 return SNMP_INTEGER(adj
->adj_usage
);
2568 case ISIS_ISADJ_HOLDTIMER
:
2570 * It seems that we want remaining timer
2572 if (adj
->last_upd
!= 0) {
2574 if (val
< ((time_t)adj
->last_upd
+ (time_t)adj
->hold_time
))
2575 return SNMP_INTEGER(adj
->last_upd
2576 + adj
->hold_time
- val
);
2578 /* Not running or just expired */
2579 return SNMP_INTEGER(0);
2581 case ISIS_ISADJ_NEIGHPRIORITY
:
2582 return SNMP_INTEGER(adj
->prio
[adj
->level
- 1]);
2584 case ISIS_ISADJ_LASTUPTIME
:
2585 if (adj
->flaps
== 0)
2586 return SNMP_INTEGER(0);
2588 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2590 now_time
= time(NULL
);
2592 if (adj
->last_flap
>= now_time
)
2593 return SNMP_INTEGER(up_ticks
);
2595 delta_ticks
= (now_time
- adj
->last_flap
) * 10;
2597 if (up_ticks
< delta_ticks
)
2598 return SNMP_INTEGER(up_ticks
);
2600 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2609 static uint8_t *isis_snmp_find_isadj_area(struct variable
*v
, oid
*name
,
2610 size_t *length
, int exact
,
2612 WriteMethod
**write_method
)
2614 /* Index circuit-id: 1-255 + adj-id: 1-... */
2618 struct isis_adjacency
*adj
;
2623 *write_method
= NULL
;
2625 if (*length
<= v
->namelen
) {
2628 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2632 oid_idx
= name
+ v
->namelen
;
2633 oid_idx_len
= *length
- v
->namelen
;
2636 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2637 ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2638 &adj
, NULL
, &data
, &data_len
);
2640 if (!res
|| oid_idx_len
!= 3)
2644 res
= isis_snmp_adj_lookup_next(
2645 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2646 &adj
, &data_idx
, &data
, &data_len
);
2650 /* Copy the name out */
2651 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2654 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2655 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2656 name
[v
->namelen
+ 2] = data_idx
;
2659 *length
= v
->namelen
+ 3;
2663 case ISIS_ISADJAREA_ADDRESS
:
2664 *var_len
= data_len
;
2674 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*v
, oid
*name
,
2675 size_t *length
, int exact
,
2677 WriteMethod
**write_method
)
2679 /* Index circuit-id 1-255 + adj-id 1-... */
2683 struct isis_adjacency
*adj
;
2688 *write_method
= NULL
;
2690 if (*length
<= v
->namelen
) {
2693 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2697 oid_idx
= name
+ v
->namelen
;
2698 oid_idx_len
= *length
- v
->namelen
;
2701 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2702 ISIS_SNMP_ADJ_DATA_IP_ADDR
,
2703 &adj
, NULL
, &data
, &data_len
);
2705 if (!res
|| oid_idx_len
!= 3)
2708 res
= isis_snmp_adj_lookup_next(
2709 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_IP_ADDR
, &adj
,
2710 &data_idx
, &data
, &data_len
);
2714 /* Copy the name out */
2715 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2718 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2719 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2720 name
[v
->namelen
+ 2] = data_idx
;
2723 *length
= v
->namelen
+ 3;
2727 case ISIS_ISADJIPADDR_TYPE
:
2729 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V4
);
2731 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V6
);
2733 case ISIS_ISADJIPADDR_ADDRESS
:
2734 *var_len
= data_len
;
2744 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*v
, oid
*name
,
2745 size_t *length
, int exact
,
2747 WriteMethod
**write_method
)
2749 /* Index circuit-id 1-255 + adj-id 1-... */
2753 struct isis_adjacency
*adj
;
2758 *write_method
= NULL
;
2760 if (*length
<= v
->namelen
) {
2763 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2767 oid_idx
= name
+ v
->namelen
;
2768 oid_idx_len
= *length
- v
->namelen
;
2771 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2772 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2773 NULL
, &data
, &data_len
);
2775 if (!res
|| oid_idx_len
!= 3)
2779 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2780 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2781 &data_idx
, &data
, &data_len
);
2785 /* Copy the name out */
2786 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2789 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2790 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2791 name
[v
->namelen
+ 2] = data_idx
;
2794 *length
= v
->namelen
+ 3;
2798 case ISIS_ISADJPROTSUPP_PROTOCOL
:
2799 return SNMP_INTEGER(*data
);
2809 /* Register ISIS-MIB. */
2810 static int isis_snmp_init(struct thread_master
*tm
)
2812 struct isis_func_to_prefix
*h2f
= isis_func_to_prefix_arr
;
2815 for (size_t off
= 0; off
< isis_var_count
; off
++) {
2816 v
= &isis_var_arr
[off
];
2818 if (v
->findVar
!= h2f
->ihtp_func
) {
2821 assert(h2f
< (isis_func_to_prefix_arr
2822 + isis_func_to_prefix_count
));
2823 assert(v
->findVar
== h2f
->ihtp_func
);
2826 v
->namelen
= h2f
->ihtp_pref_len
+ 1;
2827 memcpy(v
->name
, h2f
->ihtp_pref_oid
,
2828 h2f
->ihtp_pref_len
* sizeof(oid
));
2829 v
->name
[h2f
->ihtp_pref_len
] = v
->magic
;
2834 REGISTER_MIB("mibII/isis", isis_var_arr
, variable
, isis_oid
);
2839 * ISIS notification functions: we have one function per notification
2841 static int isis_snmp_trap_throttle(oid trap_id
)
2844 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2846 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
2849 time_now
= time(NULL
);
2851 if ((isis_snmp_trap_timestamp
[trap_id
] + 5) > time_now
)
2852 /* Throttle trap rate at 1 in 5 secs */
2855 isis_snmp_trap_timestamp
[trap_id
] = time_now
;
2859 static int isis_snmp_db_overload_update(const struct isis_area
*area
)
2861 netsnmp_variable_list
*notification_vars
;
2865 if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD
))
2868 notification_vars
= NULL
;
2870 /* Put in trap value */
2871 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2872 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2873 (uint8_t *)&isis_snmp_trap_val_db_overload
,
2874 sizeof(isis_snmp_trap_val_db_overload
));
2877 val
= area
->is_type
;
2879 snmp_varlist_add_variable(
2880 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2881 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2882 (uint8_t *)&val
, sizeof(val
));
2884 /* Patch sys_level_state with proper index */
2885 off
= ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
) - 1;
2886 isis_snmp_trap_data_var_sys_level_state
[off
] = val
;
2889 if (area
->overload_bit
)
2890 val
= ISIS_SNMP_LEVEL_STATE_OVERLOADED
;
2892 val
= ISIS_SNMP_LEVEL_STATE_ON
;
2894 snmp_varlist_add_variable(
2895 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_state
,
2896 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
), INTEGER
,
2897 (uint8_t *)&val
, sizeof(val
));
2899 send_v2trap(notification_vars
);
2900 snmp_free_varbind(notification_vars
);
2901 smux_events_update();
2905 static int isis_snmp_lsp_exceed_max_update(const struct isis_area
*area
,
2906 const uint8_t *lsp_id
)
2908 netsnmp_variable_list
*notification_vars
;
2911 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_EXCEED_MAX
))
2914 notification_vars
= NULL
;
2916 /* Put in trap value */
2917 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2918 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2919 (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max
,
2920 sizeof(isis_snmp_trap_val_lsp_exceed_max
));
2923 val
= area
->is_type
;
2925 snmp_varlist_add_variable(
2926 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2927 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2928 (uint8_t *)&val
, sizeof(val
));
2930 snmp_varlist_add_variable(
2931 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
2932 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
2933 ISIS_SYS_ID_LEN
+ 2);
2935 send_v2trap(notification_vars
);
2936 snmp_free_varbind(notification_vars
);
2937 smux_events_update();
2943 * A common function to handle popular combination of trap objects
2944 * isisNotificationSysLevelIndex,
2946 * isisNotificationCircIfIndex,
2949 static void isis_snmp_update_worker_a(const struct isis_circuit
*circuit
,
2950 oid trap_id
, const oid
*oid_a
,
2951 size_t oid_a_len
, uint8_t type_a
,
2952 const void *data_a
, size_t data_a_len
,
2953 const oid
*oid_b
, size_t oid_b_len
,
2954 uint8_t type_b
, const void *data_b
,
2957 netsnmp_variable_list
*notification_vars
= NULL
;
2958 oid var_name
[MAX_OID_LEN
];
2963 if (trap_id
!= ISIS_TRAP_ID_LEN_MISMATCH
2964 && trap_id
!= ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
2965 && trap_id
!= ISIS_TRAP_OWN_LSP_PURGE
2966 && trap_id
!= ISIS_TRAP_SEQNO_SKIPPED
2967 && trap_id
!= ISIS_TRAP_AUTHEN_TYPE_FAILURE
2968 && trap_id
!= ISIS_TRAP_AUTHEN_FAILURE
2969 && trap_id
!= ISIS_TRAP_REJ_ADJACENCY
)
2972 /* Put in trap value */
2973 memcpy(var_name
, isis_snmp_notifications
,
2974 sizeof(isis_snmp_notifications
));
2975 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
2976 var_name
[var_count
++] = trap_id
;
2978 /* Put in trap value */
2979 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2980 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2981 (uint8_t *)var_name
, var_count
* sizeof(oid
));
2983 val
= circuit
->is_type
;
2984 snmp_varlist_add_variable(
2985 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2986 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2987 (uint8_t *)&val
, sizeof(val
));
2989 if (oid_a_len
!= 0) {
2990 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
2993 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
2994 type_a
, (uint8_t *)data_a
,
2998 if (circuit
->interface
== NULL
)
3001 val
= circuit
->interface
->ifindex
;
3003 snmp_varlist_add_variable(
3004 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3005 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3006 (uint8_t *)&val
, sizeof(val
));
3009 if (oid_b_len
!= 0) {
3010 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3013 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3014 type_b
, (uint8_t *)data_b
,
3018 send_v2trap(notification_vars
);
3019 snmp_free_varbind(notification_vars
);
3020 smux_events_update();
3024 * A common function to handle popular combination of trap objects
3025 * isisNotificationSysLevelIndex,
3026 * isisNotificationCircIfIndex,
3030 * Note: the only difference with worker_a is order of circ-if-index vs
3033 static void isis_snmp_update_worker_b(const struct isis_circuit
*circuit
,
3034 oid trap_id
, const oid
*oid_a
,
3035 size_t oid_a_len
, uint8_t type_a
,
3036 const void *data_a
, size_t data_a_len
,
3037 const oid
*oid_b
, size_t oid_b_len
,
3038 uint8_t type_b
, const void *data_b
,
3041 netsnmp_variable_list
*notification_vars
= NULL
;
3042 oid var_name
[MAX_OID_LEN
];
3047 if (trap_id
!= ISIS_TRAP_VERSION_SKEW
3048 && trap_id
!= ISIS_TRAP_LSP_TOO_LARGE
3049 && trap_id
!= ISIS_TRAP_ADJ_STATE_CHANGE
)
3052 /* Put in trap value */
3053 memcpy(var_name
, isis_snmp_notifications
,
3054 sizeof(isis_snmp_notifications
));
3055 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
3056 var_name
[var_count
++] = trap_id
;
3058 /* Put in trap value */
3059 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3060 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3061 (uint8_t *)var_name
, var_count
* sizeof(oid
));
3063 val
= circuit
->is_type
;
3064 snmp_varlist_add_variable(
3065 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3066 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3067 (uint8_t *)&val
, sizeof(val
));
3069 if (circuit
->interface
== NULL
)
3072 val
= circuit
->interface
->ifindex
;
3074 snmp_varlist_add_variable(
3075 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3076 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3077 (uint8_t *)&val
, sizeof(val
));
3080 if (oid_a_len
!= 0) {
3081 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
3084 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
3085 type_a
, (uint8_t *)data_a
,
3089 if (oid_b_len
!= 0) {
3090 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3093 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3094 type_b
, (uint8_t *)data_b
,
3098 send_v2trap(notification_vars
);
3099 snmp_free_varbind(notification_vars
);
3100 smux_events_update();
3104 static int isis_snmp_id_len_mismatch_update(const struct isis_circuit
*circuit
,
3105 uint8_t rcv_id
, const char *raw_pdu
,
3110 if (!isis_snmp_trap_throttle(ISIS_TRAP_ID_LEN_MISMATCH
))
3115 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3116 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3118 isis_snmp_update_worker_a(
3119 circuit
, ISIS_TRAP_ID_LEN_MISMATCH
,
3120 isis_snmp_trap_data_var_pdu_field_len
,
3121 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_field_len
), UNSIGNED32
,
3122 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3123 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3124 raw_pdu
, raw_pdu_len
);
3129 isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit
*circuit
,
3130 uint8_t max_addrs
, const char *raw_pdu
,
3135 if (!isis_snmp_trap_throttle(ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
))
3140 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3141 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3143 isis_snmp_update_worker_a(
3144 circuit
, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
,
3145 isis_snmp_trap_data_var_pdu_max_area_addr
,
3146 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_max_area_addr
),
3147 UNSIGNED32
, &val
, sizeof(val
),
3148 isis_snmp_trap_data_var_pdu_fragment
,
3149 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3150 raw_pdu
, raw_pdu_len
);
3154 static int isis_snmp_own_lsp_purge_update(const struct isis_circuit
*circuit
,
3155 const uint8_t *lsp_id
)
3157 if (!isis_snmp_trap_throttle(ISIS_TRAP_OWN_LSP_PURGE
))
3160 isis_snmp_update_worker_a(
3161 circuit
, ISIS_TRAP_OWN_LSP_PURGE
, NULL
, 0, STRING
, NULL
, 0,
3162 isis_snmp_trap_data_var_pdu_lsp_id
,
3163 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3164 ISIS_SYS_ID_LEN
+ 2);
3168 static int isis_snmp_seqno_skipped_update(const struct isis_circuit
*circuit
,
3169 const uint8_t *lsp_id
)
3171 if (!isis_snmp_trap_throttle(ISIS_TRAP_SEQNO_SKIPPED
))
3174 isis_snmp_update_worker_a(
3175 circuit
, ISIS_TRAP_SEQNO_SKIPPED
, NULL
, 0, STRING
, NULL
, 0,
3176 isis_snmp_trap_data_var_pdu_lsp_id
,
3177 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3178 ISIS_SYS_ID_LEN
+ 2);
3183 isis_snmp_authentication_type_failure_update(const struct isis_circuit
*circuit
,
3184 const char *raw_pdu
,
3187 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_TYPE_FAILURE
))
3190 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3191 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3193 isis_snmp_update_worker_a(
3194 circuit
, ISIS_TRAP_AUTHEN_TYPE_FAILURE
, NULL
, 0, STRING
, NULL
,
3195 0, isis_snmp_trap_data_var_pdu_fragment
,
3196 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3197 raw_pdu
, raw_pdu_len
);
3202 isis_snmp_authentication_failure_update(const struct isis_circuit
*circuit
,
3203 char const *raw_pdu
, size_t raw_pdu_len
)
3205 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_FAILURE
))
3208 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3209 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3211 isis_snmp_update_worker_a(
3212 circuit
, ISIS_TRAP_AUTHEN_FAILURE
, NULL
, 0, STRING
, NULL
, 0,
3213 isis_snmp_trap_data_var_pdu_fragment
,
3214 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3215 raw_pdu
, raw_pdu_len
);
3219 static int isis_snmp_version_skew_update(const struct isis_circuit
*circuit
,
3220 uint8_t version
, const char *raw_pdu
,
3225 if (!isis_snmp_trap_throttle(ISIS_TRAP_VERSION_SKEW
))
3230 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3231 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3233 isis_snmp_update_worker_b(
3234 circuit
, ISIS_TRAP_VERSION_SKEW
,
3235 isis_snmp_trap_data_var_pdu_proto_ver
,
3236 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_proto_ver
), UNSIGNED32
,
3237 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3238 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3239 raw_pdu
, raw_pdu_len
);
3243 static int isis_snmp_area_mismatch_update(const struct isis_circuit
*circuit
,
3244 const char *raw_pdu
,
3248 * This is a special case because
3249 * it does not include isisNotificationSysLevelIndex
3251 netsnmp_variable_list
*notification_vars
;
3254 if (!isis_snmp_trap_throttle(ISIS_TRAP_AREA_MISMATCH
))
3257 notification_vars
= NULL
;
3259 /* Put in trap value */
3260 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3261 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3262 (uint8_t *)&isis_snmp_trap_val_area_mismatch
,
3263 sizeof(isis_snmp_trap_val_area_mismatch
));
3266 if (circuit
->interface
== NULL
)
3269 val
= circuit
->interface
->ifindex
;
3271 snmp_varlist_add_variable(
3272 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3273 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3274 (uint8_t *)&val
, sizeof(val
));
3277 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3278 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3280 snmp_varlist_add_variable(
3281 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3282 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3283 raw_pdu
, raw_pdu_len
);
3285 send_v2trap(notification_vars
);
3286 snmp_free_varbind(notification_vars
);
3287 smux_events_update();
3292 static int isis_snmp_reject_adjacency_update(const struct isis_circuit
*circuit
,
3293 const char *raw_pdu
,
3296 if (!isis_snmp_trap_throttle(ISIS_TRAP_REJ_ADJACENCY
))
3299 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3300 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3302 isis_snmp_update_worker_a(
3303 circuit
, ISIS_TRAP_REJ_ADJACENCY
, NULL
, 0, STRING
, NULL
, 0,
3304 isis_snmp_trap_data_var_pdu_fragment
,
3305 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3306 raw_pdu
, raw_pdu_len
);
3310 static int isis_snmp_lsp_too_large_update(const struct isis_circuit
*circuit
,
3312 const uint8_t *lsp_id
)
3314 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_TOO_LARGE
))
3317 isis_snmp_update_worker_b(
3318 circuit
, ISIS_TRAP_LSP_TOO_LARGE
,
3319 isis_snmp_trap_data_var_pdu_lsp_size
,
3320 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_size
), UNSIGNED32
,
3321 &pdu_size
, sizeof(pdu_size
), isis_snmp_trap_data_var_pdu_lsp_id
,
3322 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3323 ISIS_SYS_ID_LEN
+ 2);
3328 static int isis_snmp_adj_state_change_update(const struct isis_adjacency
*adj
)
3330 uint8_t lsp_id
[ISIS_SYS_ID_LEN
+ 2];
3332 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
3334 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
3338 memcpy(lsp_id
, adj
->sysid
, ISIS_SYS_ID_LEN
);
3339 lsp_id
[ISIS_SYS_ID_LEN
] = 0;
3340 lsp_id
[ISIS_SYS_ID_LEN
+ 1] = 0;
3342 val
= isis_snmp_adj_state(adj
->adj_state
);
3344 isis_snmp_update_worker_b(
3345 adj
->circuit
, ISIS_TRAP_ADJ_STATE_CHANGE
,
3346 isis_snmp_trap_data_var_pdu_lsp_id
,
3347 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3348 ISIS_SYS_ID_LEN
+ 2, isis_snmp_trap_data_var_adj_state
,
3349 ARRAY_SIZE(isis_snmp_trap_data_var_adj_state
), INTEGER
, &val
,
3354 static int isis_snmp_lsp_error_update(const struct isis_circuit
*circuit
,
3355 const uint8_t *lsp_id
,
3356 char const *raw_pdu
, size_t raw_pdu_len
)
3359 * This is a special case because
3360 * it have more variables
3362 netsnmp_variable_list
*notification_vars
;
3365 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_ERROR
))
3368 notification_vars
= NULL
;
3370 /* Put in trap value */
3371 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3372 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3373 (uint8_t *)&isis_snmp_trap_val_lsp_error
,
3374 sizeof(isis_snmp_trap_val_lsp_error
));
3377 val
= circuit
->is_type
;
3379 snmp_varlist_add_variable(
3380 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3381 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3382 (uint8_t *)&val
, sizeof(val
));
3385 snmp_varlist_add_variable(
3386 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
3387 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3388 ISIS_SYS_ID_LEN
+ 2);
3391 if (circuit
->interface
== NULL
)
3394 val
= circuit
->interface
->ifindex
;
3396 snmp_varlist_add_variable(
3397 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3398 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3399 (uint8_t *)&val
, sizeof(val
));
3402 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3403 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3405 snmp_varlist_add_variable(
3406 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3407 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3408 raw_pdu
, raw_pdu_len
);
3413 snmp_varlist_add_variable(
3414 ¬ification_vars
, isis_snmp_trap_data_var_error_offset
,
3415 ARRAY_SIZE(isis_snmp_trap_data_var_error_offset
), UNSIGNED32
,
3416 (uint8_t *)&val
, sizeof(val
));
3421 snmp_varlist_add_variable(
3422 ¬ification_vars
, isis_snmp_trap_data_var_error_tlv_type
,
3423 ARRAY_SIZE(isis_snmp_trap_data_var_error_tlv_type
), UNSIGNED32
,
3424 (uint8_t *)&val
, sizeof(val
));
3426 send_v2trap(notification_vars
);
3427 snmp_free_varbind(notification_vars
);
3428 smux_events_update();
3433 static int isis_snmp_module_init(void)
3435 hook_register(isis_hook_db_overload
, isis_snmp_db_overload_update
);
3436 hook_register(isis_hook_lsp_exceed_max
,
3437 isis_snmp_lsp_exceed_max_update
);
3438 hook_register(isis_hook_id_len_mismatch
,
3439 isis_snmp_id_len_mismatch_update
);
3440 hook_register(isis_hook_max_area_addr_mismatch
,
3441 isis_snmp_max_area_addr_mismatch_update
);
3442 hook_register(isis_hook_own_lsp_purge
, isis_snmp_own_lsp_purge_update
);
3443 hook_register(isis_hook_seqno_skipped
, isis_snmp_seqno_skipped_update
);
3444 hook_register(isis_hook_authentication_type_failure
,
3445 isis_snmp_authentication_type_failure_update
);
3446 hook_register(isis_hook_authentication_failure
,
3447 isis_snmp_authentication_failure_update
);
3448 hook_register(isis_hook_version_skew
, isis_snmp_version_skew_update
);
3449 hook_register(isis_hook_area_mismatch
, isis_snmp_area_mismatch_update
);
3450 hook_register(isis_hook_reject_adjacency
,
3451 isis_snmp_reject_adjacency_update
);
3452 hook_register(isis_hook_lsp_too_large
, isis_snmp_lsp_too_large_update
);
3453 hook_register(isis_hook_adj_state_change
,
3454 isis_snmp_adj_state_change_update
);
3455 hook_register(isis_hook_lsp_error
, isis_snmp_lsp_error_update
);
3456 hook_register(isis_circuit_new_hook
, isis_circuit_snmp_id_gen
);
3457 hook_register(isis_circuit_del_hook
, isis_circuit_snmp_id_free
);
3459 hook_register(frr_late_init
, isis_snmp_init
);
3464 .name
= "isis_snmp",
3465 .version
= FRR_VERSION
,
3466 .description
= "isis AgentX SNMP module",
3467 .init
= isis_snmp_module_init
,