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>
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
286 #ifndef ISIS_SNMP_HAVE_TIME_FUNC
287 static uint32_t isis_snmp_time(void)
289 return (uint32_t)time(NULL
);
294 /* ISIS-MIB instances. */
295 static oid isis_oid
[] = {ISIS_MIB
};
297 /* SNMP trap variable */
298 static oid isis_snmp_trap_var
[] = {ISIS_SNMP_TRAP_VAR
};
300 /* SNMP trap values (others are calculated on the fly */
301 static oid isis_snmp_notifications
[] = {ISIS_NOTIFICATIONS
};
302 static oid isis_snmp_trap_val_db_overload
[] = {ISIS_NOTIFICATIONS
,
303 ISIS_TRAP_DB_OVERLOAD
};
304 static oid isis_snmp_trap_val_lsp_exceed_max
[] = {ISIS_NOTIFICATIONS
,
305 ISIS_TRAP_LSP_EXCEED_MAX
};
306 static oid isis_snmp_trap_val_area_mismatch
[] = {ISIS_NOTIFICATIONS
,
307 ISIS_TRAP_AREA_MISMATCH
};
308 static oid isis_snmp_trap_val_lsp_error
[] = {ISIS_NOTIFICATIONS
,
309 ISIS_TRAP_LSP_ERROR
};
312 * Trap vars under 'isisNotifications': note: we use full names of variables
315 static oid isis_snmp_trap_data_var_sys_level_index
[] = {
316 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_SYLELVELINDEX
, 0};
317 static oid isis_snmp_trap_data_var_circ_if_index
[] = {
318 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_NOTIF_CIRCIFINDEX
, 0};
319 static oid isis_snmp_trap_data_var_pdu_lsp_id
[] = {
320 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPID
, 0};
321 static oid isis_snmp_trap_data_var_pdu_fragment
[] = {
322 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FRAGMENT
, 0};
323 static oid isis_snmp_trap_data_var_pdu_field_len
[] = {
324 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_FIELDLEN
, 0};
325 static oid isis_snmp_trap_data_var_pdu_max_area_addr
[] = {
326 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_MAXAREAADDR
, 0};
327 static oid isis_snmp_trap_data_var_pdu_proto_ver
[] = {
328 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_PROTOVER
, 0};
329 static oid isis_snmp_trap_data_var_pdu_lsp_size
[] = {
330 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_PDU_LSPSIZE
, 0};
331 static oid isis_snmp_trap_data_var_adj_state
[] = {
332 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ADJ_STATE
, 0};
333 static oid isis_snmp_trap_data_var_error_offset
[] = {
334 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_OFFSET
, 0};
335 static oid isis_snmp_trap_data_var_error_tlv_type
[] = {
336 ISIS_MIB
, ISIS_NOTIFICATION_ENTRY
, ISIS_ERROR_TLVTYPE
, 0};
339 * Other variables used by traps: note we use full names of variables and
340 * reserve space for index
342 static oid isis_snmp_trap_data_var_sys_level_state
[] = {
343 ISIS_MIB
, ISIS_SYSLEVEL_ENTRY
, ISIS_SYSLEVEL_STATE
, 0};
345 /* Throttle time values for traps */
346 static time_t isis_snmp_trap_timestamp
[ISIS_TRAP_LAST_TRAP
]; /* ?? 1 */
348 /* Max len of raw-pdu in traps */
349 #define ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN (64)
352 * Just to save on typing we have a shortcut structure
353 * to specify mib layout as prefix/leaf combination
355 #define ISIS_SNMP_PREF_LEN_MAX 10
356 struct isis_var_prefix
{
357 FindVarMethod
*findVar
;
358 uint8_t ivd_pref_len
;
359 oid ivd_pref
[ISIS_SNMP_PREF_LEN_MAX
];
363 /* Find-val functions */
364 static uint8_t *isis_snmp_find_sys_object(struct variable
*, oid
*, size_t *,
365 int, size_t *, WriteMethod
**);
367 static uint8_t *isis_snmp_find_man_area(struct variable
*, oid
*, size_t *, int,
368 size_t *, WriteMethod
**);
370 static uint8_t *isis_snmp_find_area_addr(struct variable
*, oid
*, size_t *,
371 int, size_t *, WriteMethod
**);
373 static uint8_t *isis_snmp_find_summ_addr(struct variable
*, oid
*, size_t *,
374 int, size_t *, WriteMethod
**);
376 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*, oid
*,
377 size_t *, int, size_t *,
380 static uint8_t *isis_snmp_find_router(struct variable
*, oid
*, size_t *, int,
381 size_t *, WriteMethod
**);
383 static uint8_t *isis_snmp_find_sys_level(struct variable
*, oid
*, size_t *,
384 int, size_t *, WriteMethod
**);
386 static uint8_t *isis_snmp_find_system_counter(struct variable
*, oid
*,
387 size_t *, int, size_t *,
390 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*, oid
*,
391 size_t *, int, size_t *,
394 static uint8_t *isis_snmp_find_circ(struct variable
*, oid
*, size_t *, int,
395 size_t *, WriteMethod
**);
397 static uint8_t *isis_snmp_find_circ_level(struct variable
*, oid
*, size_t *,
398 int, size_t *, WriteMethod
**);
400 static uint8_t *isis_snmp_find_circ_counter(struct variable
*, oid
*, size_t *,
401 int, size_t *, WriteMethod
**);
403 static uint8_t *isis_snmp_find_isadj(struct variable
*, oid
*, size_t *, int,
404 size_t *, WriteMethod
**);
406 static uint8_t *isis_snmp_find_isadj_area(struct variable
*, oid
*, size_t *,
407 int, size_t *, WriteMethod
**);
409 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*, oid
*, size_t *,
410 int, size_t *, WriteMethod
**);
412 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*, oid
*,
413 size_t *, int, size_t *,
417 * Just to save on typing we have a shortcut structure
418 * to specify mib layout, we populate the rest of the data
419 * during initialization
421 #define ISIS_PREF_LEN_MAX (6)
423 struct isis_func_to_prefix
{
424 FindVarMethod
*ihtp_func
;
425 oid ihtp_pref_oid
[ISIS_PREF_LEN_MAX
];
426 uint8_t ihtp_pref_len
;
429 static struct isis_func_to_prefix isis_func_to_prefix_arr
[] = {
430 {isis_snmp_find_sys_object
, {ISIS_SYS_OBJECT
}, 3},
431 {isis_snmp_find_man_area
, {ISIS_MANAREA_ADDRENTRY
}, 4},
432 {isis_snmp_find_area_addr
, {ISIS_AREA_ADDRENTRY
}, 4},
433 {isis_snmp_find_summ_addr
, {ISIS_SUMM_ADDRENTRY
}, 4},
434 {isis_snmp_find_redistribute_addr
, {ISIS_REDISTRIBUTE_ADDRENTRY
}, 4},
435 {isis_snmp_find_router
, {ISIS_ROUTER_ENTRY
}, 4},
436 {isis_snmp_find_sys_level
, {ISIS_SYSLEVEL_ENTRY
}, 4},
437 {isis_snmp_find_system_counter
, {ISIS_SYSTEM_COUNTER_ENTRY
}, 4},
438 {isis_snmp_find_next_circ_index
, {ISIS_CIRC
}, 2},
439 {isis_snmp_find_circ
, {ISIS_CIRC_ENTRY
}, 4},
440 {isis_snmp_find_circ_level
, {ISIS_CIRCLEVEL_ENTRY
}, 4},
441 {isis_snmp_find_circ_counter
, {ISIS_CIRC_COUNTER_ENTRY
}, 4},
442 {isis_snmp_find_isadj
, {ISIS_ISADJ_ENTRY
}, 4},
443 {isis_snmp_find_isadj_area
, {ISIS_ISADJAREA_ADDRENTRY
}, 4},
444 {isis_snmp_find_isadj_ipaddr
, {ISIS_ISADJIPADDR_ENTRY
}, 4},
445 {isis_snmp_find_isadj_prot_supp
, {ISIS_ISADJPROTSUPP_ENTRY
}, 4},
447 static size_t isis_func_to_prefix_count
= ARRAY_SIZE(isis_func_to_prefix_arr
);
449 static struct variable isis_var_arr
[] = {
450 {ISIS_SYS_VERSION
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
451 {ISIS_SYS_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
452 {ISIS_SYS_ID
, STRING
, RONLY
, isis_snmp_find_sys_object
},
453 {ISIS_SYS_MAXPATHSPLITS
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
454 {ISIS_SYS_MAXLSPGENINT
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
455 {ISIS_SYS_POLLESHELLORATE
, UNSIGNED32
, RONLY
,
456 isis_snmp_find_sys_object
},
457 {ISIS_SYS_WAITTIME
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
458 {ISIS_SYS_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
459 {ISIS_SYS_L2TOL1LEAKING
, INTEGER
, RONLY
, isis_snmp_find_sys_object
},
460 {ISIS_SYS_MAXAGE
, UNSIGNED32
, RONLY
, isis_snmp_find_sys_object
},
461 {ISIS_SYS_RECEIVELSPBUFFERSIZE
, UNSIGNED32
, RONLY
,
462 isis_snmp_find_sys_object
},
463 {ISIS_SYS_PROTSUPPORTED
, STRING
, RONLY
, isis_snmp_find_sys_object
},
464 {ISIS_SYS_NOTIFICATIONENABLE
, INTEGER
, RONLY
,
465 isis_snmp_find_sys_object
},
466 {ISIS_MANAREA_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_man_area
},
467 {ISIS_AREA_ADDR
, STRING
, RONLY
, isis_snmp_find_area_addr
},
468 {ISIS_SUMM_ADDREXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_summ_addr
},
469 {ISIS_SUMM_ADDRMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
470 {ISIS_SUMM_ADDRFULLMETRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_summ_addr
},
471 {ISIS_REDISTRIBUTE_ADDREXISTSTATE
, INTEGER
, RONLY
,
472 isis_snmp_find_redistribute_addr
},
473 {ISIS_ROUTER_HOSTNAME
, STRING
, RONLY
, isis_snmp_find_router
},
474 {ISIS_ROUTER_ID
, UNSIGNED32
, RONLY
, isis_snmp_find_router
},
475 {ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
, UNSIGNED32
, RONLY
,
476 isis_snmp_find_sys_level
},
477 {ISIS_SYSLEVEL_MINLSPGENINT
, UNSIGNED32
, RONLY
,
478 isis_snmp_find_sys_level
},
479 {ISIS_SYSLEVEL_STATE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
480 {ISIS_SYSLEVEL_SETOVERLOAD
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
481 {ISIS_SYSLEVEL_SETOVERLOADUNTIL
, UNSIGNED32
, RONLY
,
482 isis_snmp_find_sys_level
},
483 {ISIS_SYSLEVEL_METRICSTYLE
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
484 {ISIS_SYSLEVEL_SPFCONSIDERS
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
485 {ISIS_SYSLEVEL_TEENABLED
, INTEGER
, RONLY
, isis_snmp_find_sys_level
},
486 {ISIS_SYSSTAT_CORRLSPS
, COUNTER32
, RONLY
,
487 isis_snmp_find_system_counter
},
488 {ISIS_SYSSTAT_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
489 isis_snmp_find_system_counter
},
490 {ISIS_SYSSTAT_AUTHFAILS
, COUNTER32
, RONLY
,
491 isis_snmp_find_system_counter
},
492 {ISIS_SYSSTAT_LSPDBASEOLOADS
, COUNTER32
, RONLY
,
493 isis_snmp_find_system_counter
},
494 {ISIS_SYSSTAT_MANADDRDROPFROMAREAS
, COUNTER32
, RONLY
,
495 isis_snmp_find_system_counter
},
496 {ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
, COUNTER32
, RONLY
,
497 isis_snmp_find_system_counter
},
498 {ISIS_SYSSTAT_SEQNUMSKIPS
, COUNTER32
, RONLY
,
499 isis_snmp_find_system_counter
},
500 {ISIS_SYSSTAT_OWNLSPPURGES
, COUNTER32
, RONLY
,
501 isis_snmp_find_system_counter
},
502 {ISIS_SYSSTAT_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
503 isis_snmp_find_system_counter
},
504 {ISIS_SYSSTAT_PARTCHANGES
, COUNTER32
, RONLY
,
505 isis_snmp_find_system_counter
},
506 {ISIS_SYSSTAT_SPFRUNS
, COUNTER32
, RONLY
, isis_snmp_find_system_counter
},
507 {ISIS_SYSSTAT_LSPERRORS
, COUNTER32
, RONLY
,
508 isis_snmp_find_system_counter
},
509 {ISIS_NEXTCIRC_INDEX
, UNSIGNED32
, RONLY
,
510 isis_snmp_find_next_circ_index
},
511 {ISIS_CIRC_IFINDEX
, INTEGER
, RONLY
, isis_snmp_find_circ
},
512 {ISIS_CIRC_ADMINSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
513 {ISIS_CIRC_EXISTSTATE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
514 {ISIS_CIRC_TYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
515 {ISIS_CIRC_EXTDOMAIN
, INTEGER
, RONLY
, isis_snmp_find_circ
},
516 {ISIS_CIRC_LEVELTYPE
, INTEGER
, RONLY
, isis_snmp_find_circ
},
517 {ISIS_CIRC_PASSIVECIRCUIT
, INTEGER
, RONLY
, isis_snmp_find_circ
},
518 {ISIS_CIRC_MESHGROUPENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
519 {ISIS_CIRC_MESHGROUP
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
520 {ISIS_CIRC_SMALLHELLOS
, INTEGER
, RONLY
, isis_snmp_find_circ
},
521 {ISIS_CIRC_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_circ
},
522 {ISIS_CIRC_3WAYENABLED
, INTEGER
, RONLY
, isis_snmp_find_circ
},
523 {ISIS_CIRC_EXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_circ
},
524 {ISIS_CIRCLEVEL_METRIC
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
525 {ISIS_CIRCLEVEL_WIDEMETRIC
, UNSIGNED32
, RONLY
,
526 isis_snmp_find_circ_level
},
527 {ISIS_CIRCLEVEL_ISPRIORITY
, UNSIGNED32
, RONLY
,
528 isis_snmp_find_circ_level
},
529 {ISIS_CIRCLEVEL_IDOCTET
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_level
},
530 {ISIS_CIRCLEVEL_ID
, STRING
, RONLY
, isis_snmp_find_circ_level
},
531 {ISIS_CIRCLEVEL_DESIS
, STRING
, RONLY
, isis_snmp_find_circ_level
},
532 {ISIS_CIRCLEVEL_HELLOMULTIPLIER
, UNSIGNED32
, RONLY
,
533 isis_snmp_find_circ_level
},
534 {ISIS_CIRCLEVEL_HELLOTIMER
, UNSIGNED32
, RONLY
,
535 isis_snmp_find_circ_level
},
536 {ISIS_CIRCLEVEL_DRHELLOTIMER
, UNSIGNED32
, RONLY
,
537 isis_snmp_find_circ_level
},
538 {ISIS_CIRCLEVEL_LSPTHROTTLE
, UNSIGNED32
, RONLY
,
539 isis_snmp_find_circ_level
},
540 {ISIS_CIRCLEVEL_MINLSPRETRANSINT
, UNSIGNED32
, RONLY
,
541 isis_snmp_find_circ_level
},
542 {ISIS_CIRCLEVEL_CSNPINTERVAL
, UNSIGNED32
, RONLY
,
543 isis_snmp_find_circ_level
},
544 {ISIS_CIRCLEVEL_PARTSNPINTERVAL
, UNSIGNED32
, RONLY
,
545 isis_snmp_find_circ_level
},
546 {ISIS_CIRC_ADJCHANGES
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
547 {ISIS_CIRC_NUMADJ
, UNSIGNED32
, RONLY
, isis_snmp_find_circ_counter
},
548 {ISIS_CIRC_INITFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
549 {ISIS_CIRC_REJADJS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
550 {ISIS_CIRC_IDFIELDLENMISMATCHES
, COUNTER32
, RONLY
,
551 isis_snmp_find_circ_counter
},
552 {ISIS_CIRC_MAXAREAADDRMISMATCHES
, COUNTER32
, RONLY
,
553 isis_snmp_find_circ_counter
},
554 {ISIS_CIRC_AUTHTYPEFAILS
, COUNTER32
, RONLY
,
555 isis_snmp_find_circ_counter
},
556 {ISIS_CIRC_AUTHFAILS
, COUNTER32
, RONLY
, isis_snmp_find_circ_counter
},
557 {ISIS_CIRC_LANDESISCHANGES
, COUNTER32
, RONLY
,
558 isis_snmp_find_circ_counter
},
559 {ISIS_ISADJ_STATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
560 {ISIS_ISADJ_3WAYSTATE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
561 {ISIS_ISADJ_NEIGHSNPAADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj
},
562 {ISIS_ISADJ_NEIGHSYSTYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
563 {ISIS_ISADJ_NEIGHSYSID
, STRING
, RONLY
, isis_snmp_find_isadj
},
564 {ISIS_ISADJ_NBREXTENDEDCIRCID
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
565 {ISIS_ISADJ_USAGE
, INTEGER
, RONLY
, isis_snmp_find_isadj
},
566 {ISIS_ISADJ_HOLDTIMER
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
567 {ISIS_ISADJ_NEIGHPRIORITY
, UNSIGNED32
, RONLY
, isis_snmp_find_isadj
},
568 {ISIS_ISADJ_LASTUPTIME
, TIMESTAMP
, RONLY
, isis_snmp_find_isadj
},
569 {ISIS_ISADJAREA_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_area
},
570 {ISIS_ISADJIPADDR_TYPE
, INTEGER
, RONLY
, isis_snmp_find_isadj_ipaddr
},
571 {ISIS_ISADJIPADDR_ADDRESS
, STRING
, RONLY
, isis_snmp_find_isadj_ipaddr
},
572 {ISIS_ISADJPROTSUPP_PROTOCOL
, INTEGER
, RONLY
,
573 isis_snmp_find_isadj_prot_supp
},
576 static const size_t isis_var_count
= ARRAY_SIZE(isis_var_arr
);
578 /* Minimal set of hard-coded data */
579 #define ISIS_VERSION (1)
581 /* If sys-id is not set use this value */
582 static uint8_t isis_null_sysid
[ISIS_SYS_ID_LEN
];
585 #define ISIS_SNMP_OSI_ADDR_LEN_MAX (20)
588 * The implementation has a fixed max-path splits value
589 * of 64 (see ISIS_MAX_PATH_SPLITS), the max mib value
592 * FIXME(aromanov): should we return 32 or 64?
594 #define ISIS_SNMP_MAX_PATH_SPLITS (32)
596 #define ISIS_SNMP_ADMIN_STATE_ON (1)
598 #define ISIS_SNMP_ROW_STATUS_ACTIVE (1)
600 #define ISIS_SNMP_LEVEL_STATE_OFF (1)
601 #define ISIS_SNMP_LEVEL_STATE_ON (2)
602 #define ISIS_SNMP_LEVEL_STATE_WAITING (3)
603 #define ISIS_SNMP_LEVEL_STATE_OVERLOADED (4)
605 #define ISIS_SNMP_TRUTH_VALUE_TRUE (1)
606 #define ISIS_SNMP_TRUTH_VALUE_FALSE (2)
608 #define ISIS_SNMP_METRIC_STYLE_NARROW (1)
609 #define ISIS_SNMP_METRIC_STYLE_WIDE (2)
610 #define ISIS_SNMP_METRIC_STYLE_BOTH (3)
612 #define ISIS_SNMP_MESH_GROUP_INACTIVE (1)
614 #define ISIS_SNMP_ADJ_STATE_DOWN (1)
615 #define ISIS_SNMP_ADJ_STATE_INITIALIZING (2)
616 #define ISIS_SNMP_ADJ_STATE_UP (3)
617 #define ISIS_SNMP_ADJ_STATE_FAILED (4)
619 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1 (1)
620 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2 (2)
621 #define ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2 (3)
622 #define ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN (4)
624 #define ISIS_SNMP_INET_TYPE_V4 (1)
625 #define ISIS_SNMP_INET_TYPE_V6 (2)
627 #define ISIS_SNMP_P2P_CIRCUIT (3)
629 /* Protocols supported value */
630 static uint8_t isis_snmp_protocols_supported
= 0x7; /* All: iso, ipv4, ipv6 */
633 * Convenience function to move to the next circuit,
635 static struct isis_circuit
*isis_snmp_circuit_next(struct isis_circuit
*circuit
)
639 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
647 start
= circuit
->snmp_id
+ 1;
649 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
650 circuit
= isis
->snmp_circuits
[off
];
660 * Convenience function to get the first matching level
662 static int isis_snmp_circuit_get_level_lo(struct isis_circuit
*circuit
)
664 if (circuit
->is_type
== IS_LEVEL_2
)
670 /* Check level match */
671 static int isis_snmp_get_level_match(int is_type
, int level
)
673 if (is_type
!= IS_LEVEL_1
&& is_type
!= IS_LEVEL_2
674 && is_type
!= IS_LEVEL_1_AND_2
)
677 if (level
!= IS_LEVEL_1
&& level
!= IS_LEVEL_2
)
681 if (is_type
== IS_LEVEL_1
) {
682 if (level
== IS_LEVEL_1
)
688 if (is_type
== IS_LEVEL_2
) {
689 if (level
== IS_LEVEL_2
)
698 * Helper function to convert oid index representing
699 * octet-string index (e.g. isis-sys-id) to byte string
700 * representing the same index.
702 * Also we do not fail if idx is longer than max_len,
703 * so we can use the same function to check compound
706 static int isis_snmp_conv_exact(uint8_t *buf
, size_t max_len
, size_t *out_len
,
707 const oid
*idx
, size_t idx_len
)
712 /* Oid representation: length followed by bytes */
713 if (idx
== NULL
|| idx_len
== 0)
721 if (idx_len
< len
+ 1)
724 for (off
= 0; off
< len
; off
++) {
725 if (idx
[off
+ 1] > 0xff)
728 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
736 static int isis_snmp_conv_next(uint8_t *buf
, size_t max_len
, size_t *out_len
,
737 int *try_exact
, const oid
*idx
, size_t idx_len
)
743 if (idx
== NULL
|| idx_len
== 0) {
756 if ((idx_len
- 1) < cmp_len
)
757 cmp_len
= idx_len
- 1;
759 for (off
= 0; off
< cmp_len
; off
++) {
760 if (idx
[off
+ 1] > 0xff) {
761 memset(buf
+ off
, 0xff, len
- off
);
767 buf
[off
] = (uint8_t)(idx
[off
+ 1] & 0xff);
771 memset(buf
+ cmp_len
, 0, len
- cmp_len
);
774 *try_exact
= cmp_len
< len
? 1 : 0;
779 * Helper functions to find area address from snmp index
781 static int isis_snmp_area_addr_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
782 struct isis_area
**ret_area
,
783 struct area_addr
**ret_addr
)
785 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
787 struct isis_area
*area
= NULL
;
788 struct area_addr
*addr
= NULL
;
789 struct listnode
*addr_node
;
790 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
795 if (list_isempty(isis
->area_list
)) {
796 /* Area is not configured yet */
800 area
= listgetdata(listhead(isis
->area_list
));
802 int res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
803 oid_idx
, oid_idx_len
);
806 if (!res
|| addr_len
== 0 || oid_idx_len
!= (addr_len
+ 1)) {
807 /* Bad conversion, empty address or extra oids at the end */
811 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
812 if (addr
->addr_len
!= addr_len
)
815 if (memcmp(addr
->area_addr
, cmp_buf
, addr_len
) == 0) {
828 static int isis_snmp_area_addr_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
829 struct isis_area
**ret_area
,
830 struct area_addr
**ret_addr
)
832 uint8_t cmp_buf
[ISIS_SNMP_OSI_ADDR_LEN_MAX
];
835 struct isis_area
*found_area
= NULL
;
836 struct isis_area
*area
= NULL
;
837 struct area_addr
*found_addr
= NULL
;
838 struct area_addr
*addr
= NULL
;
839 struct listnode
*addr_node
;
840 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
845 if (list_isempty(isis
->area_list
)) {
846 /* Area is not configured yet */
850 area
= listgetdata(listhead(isis
->area_list
));
852 int res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &addr_len
,
853 &try_exact
, oid_idx
, oid_idx_len
);
858 for (ALL_LIST_ELEMENTS_RO(area
->area_addrs
, addr_node
, addr
)) {
859 if (addr
->addr_len
< addr_len
)
862 if (addr
->addr_len
== addr_len
) {
866 res
= memcmp(addr
->area_addr
, cmp_buf
, addr_len
);
871 if (res
== 0 && addr
->addr_len
== addr_len
) {
874 * This is the best match no point
885 if (found_addr
== NULL
|| addr
->addr_len
< found_addr
->addr_len
886 || (addr
->addr_len
== found_addr
->addr_len
887 && memcmp(addr
->area_addr
, found_addr
->area_addr
,
895 if (found_area
== NULL
)
899 *ret_area
= found_area
;
902 *ret_addr
= found_addr
;
908 * Helper functions to find circuit from
911 static int isis_snmp_circuit_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
912 struct isis_circuit
**ret_circuit
)
914 struct isis_circuit
*circuit
;
915 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
920 if (oid_idx
== NULL
|| oid_idx_len
< 1
921 || oid_idx
[0] > SNMP_CIRCUITS_MAX
)
924 circuit
= isis
->snmp_circuits
[oid_idx
[0]];
928 if (ret_circuit
!= NULL
)
929 *ret_circuit
= circuit
;
934 static int isis_snmp_circuit_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
935 struct isis_circuit
**ret_circuit
)
939 struct isis_circuit
*circuit
;
940 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
947 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
948 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
954 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; ++off
) {
955 circuit
= isis
->snmp_circuits
[off
];
957 if (circuit
!= NULL
&& off
> start
) {
958 if (ret_circuit
!= NULL
)
959 *ret_circuit
= circuit
;
969 * Helper functions to find circuit level
970 * combination from snmp index
972 static int isis_snmp_circuit_level_lookup_exact(
973 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
974 struct isis_circuit
**ret_circuit
, int *ret_level
)
978 struct isis_circuit
*circuit
;
980 /* Minor optimization: check level first */
981 if (oid_idx
== NULL
|| oid_idx_len
< 2)
984 if (oid_idx
[1] < IS_LEVEL_1
|| oid_idx
[1] > IS_LEVEL_2
)
987 level
= (int)oid_idx
[1];
989 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
994 if (check_match
&& !isis_snmp_get_level_match(circuit
->is_type
, level
))
997 if (ret_circuit
!= NULL
)
998 *ret_circuit
= circuit
;
1000 if (ret_level
!= NULL
)
1006 static int isis_snmp_circuit_level_lookup_next(
1007 oid
*oid_idx
, size_t oid_idx_len
, int check_match
,
1008 struct isis_circuit
**ret_circuit
, int *ret_level
)
1012 struct isis_circuit
*circuit
;
1014 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1021 if (oid_idx
!= NULL
&& oid_idx_len
!= 0) {
1022 if (oid_idx
[0] > SNMP_CIRCUITS_MAX
)
1028 for (off
= start
; off
< SNMP_CIRCUITS_MAX
; off
++) {
1029 circuit
= isis
->snmp_circuits
[off
];
1031 if (circuit
== NULL
)
1034 if (off
> start
|| oid_idx_len
< 2) {
1035 /* Found and can use level 1 */
1040 /* We have to check level specified by index */
1041 if (oid_idx
[1] < IS_LEVEL_1
) {
1046 if (oid_idx
[1] < IS_LEVEL_2
) {
1055 if (circuit
== NULL
)
1059 && !isis_snmp_get_level_match(circuit
->is_type
, level
)) {
1060 if (level
== IS_LEVEL_1
) {
1062 * We can simply advance level because
1063 * at least one level should match
1067 /* We have to move to the next circuit */
1068 circuit
= isis_snmp_circuit_next(circuit
);
1069 if (circuit
== NULL
)
1072 level
= isis_snmp_circuit_get_level_lo(circuit
);
1076 if (ret_circuit
!= NULL
)
1077 *ret_circuit
= circuit
;
1079 if (ret_level
!= NULL
)
1086 * Helper functions to find adjacency
1089 * We have 4 tables related to adjacency
1090 * looking up adjacency is quite expensive
1091 * in case of bcast interfaces.
1093 * It is pain to have 4 very similar functions
1094 * hence we pass in and out additional data
1095 * we are looking for.
1097 * Note: we use data-len value to distinguish
1098 * between ipv4 and ipv6 addresses
1100 #define ISIS_SNMP_ADJ_DATA_NONE (1)
1101 #define ISIS_SNMP_ADJ_DATA_AREA_ADDR (2)
1102 #define ISIS_SNMP_ADJ_DATA_IP_ADDR (3)
1103 #define ISIS_SNMP_ADJ_DATA_PROTO (4)
1106 * Helper function to process data associated
1109 static int isis_snmp_adj_helper(struct isis_adjacency
*adj
, int data_id
,
1110 oid data_off
, uint8_t **ret_data
,
1111 size_t *ret_data_len
)
1113 uint8_t *data
= NULL
;
1114 size_t data_len
= 0;
1117 case ISIS_SNMP_ADJ_DATA_NONE
:
1120 case ISIS_SNMP_ADJ_DATA_AREA_ADDR
:
1121 if (data_off
>= adj
->area_address_count
)
1124 data
= adj
->area_addresses
[data_off
].area_addr
;
1125 data_len
= adj
->area_addresses
[data_off
].addr_len
;
1128 case ISIS_SNMP_ADJ_DATA_IP_ADDR
:
1130 >= (adj
->ipv4_address_count
+ adj
->ipv6_address_count
))
1133 if (data_off
>= adj
->ipv4_address_count
) {
1134 data
= (uint8_t *)&adj
->ipv6_addresses
1135 [data_off
- adj
->ipv4_address_count
];
1136 data_len
= sizeof(adj
->ipv6_addresses
[0]);
1138 data
= (uint8_t *)&adj
->ipv4_addresses
[data_off
];
1139 data_len
= sizeof(adj
->ipv4_addresses
[0]);
1145 case ISIS_SNMP_ADJ_DATA_PROTO
:
1146 if (data_off
>= adj
->nlpids
.count
)
1149 data
= &adj
->nlpids
.nlpids
[data_off
];
1150 data_len
= sizeof(adj
->nlpids
.nlpids
[0]);
1158 if (ret_data
!= NULL
)
1161 if (ret_data_len
!= NULL
)
1162 *ret_data_len
= data_len
;
1167 static int isis_snmp_adj_lookup_exact(oid
*oid_idx
, size_t oid_idx_len
,
1169 struct isis_adjacency
**ret_adj
,
1170 oid
*ret_data_idx
, uint8_t **ret_data
,
1171 size_t *ret_data_len
)
1174 struct listnode
*node
;
1175 struct isis_circuit
*circuit
;
1176 struct isis_adjacency
*adj
;
1177 struct isis_adjacency
*tmp_adj
;
1183 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
, &circuit
);
1188 if (oid_idx
== NULL
|| oid_idx_len
< 2
1189 || (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
&& oid_idx_len
< 3))
1192 adj_idx
= oid_idx
[1];
1194 if (data_id
!= ISIS_SNMP_ADJ_DATA_NONE
) {
1195 if (oid_idx
[2] == 0)
1198 data_off
= oid_idx
[2] - 1;
1201 * Data-off is not used if data-id is none
1202 * but we set it just for consistency
1211 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
, tmp_adj
)) {
1212 if (tmp_adj
->snmp_idx
> adj_idx
) {
1214 * Adjacencies are ordered in the list
1215 * no point to look further
1220 if (tmp_adj
->snmp_idx
== adj_idx
) {
1221 res
= isis_snmp_adj_helper(tmp_adj
, data_id
, data_off
,
1233 if (ret_adj
!= NULL
)
1236 if (ret_data_idx
!= NULL
)
1237 *ret_data_idx
= data_off
+ 1;
1243 *ret_data_len
= data_len
;
1248 static int isis_snmp_adj_lookup_next(oid
*oid_idx
, size_t oid_idx_len
,
1250 struct isis_adjacency
**ret_adj
,
1251 oid
*ret_data_idx
, uint8_t **ret_data
,
1252 size_t *ret_data_len
)
1254 struct listnode
*node
;
1255 struct isis_circuit
*circuit
;
1256 struct isis_adjacency
*adj
;
1257 struct isis_adjacency
*tmp_adj
;
1269 * Note: we rely on the fact that data indexes are consequtive
1273 if (oid_idx
== 0 || oid_idx_len
== 0) {
1277 } else if (oid_idx_len
== 1) {
1278 circ_idx
= oid_idx
[0];
1281 } else if (oid_idx_len
== 2) {
1282 circ_idx
= oid_idx
[0];
1283 adj_idx
= oid_idx
[1];
1286 circ_idx
= oid_idx
[0];
1287 adj_idx
= oid_idx
[1];
1289 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1292 data_idx
= oid_idx
[2];
1295 if (!isis_snmp_circuit_lookup_exact(&circ_idx
, 1, &circuit
)
1296 && !isis_snmp_circuit_lookup_next(&circ_idx
, 1, &circuit
))
1300 if (circuit
->snmp_id
!= circ_idx
) {
1301 /* Match is not exact */
1308 * Note: the simple loop below will work in all cases
1310 while (circuit
!= NULL
) {
1311 for (ALL_LIST_ELEMENTS_RO(circuit
->snmp_adj_list
, node
,
1313 if (tmp_adj
->snmp_idx
< adj_idx
)
1316 if (tmp_adj
->snmp_idx
== adj_idx
1317 && data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1320 if (adj_idx
!= 0 && tmp_adj
->snmp_idx
> adj_idx
)
1323 if (isis_snmp_adj_helper(tmp_adj
, data_id
, data_idx
,
1324 &data
, &data_len
)) {
1333 circuit
= isis_snmp_circuit_next(circuit
);
1342 if (ret_adj
!= NULL
)
1345 if (ret_data_idx
!= 0) {
1346 if (data_id
== ISIS_SNMP_ADJ_DATA_NONE
)
1348 * Value does not matter but let us set
1349 * it to zero for consistency
1353 *ret_data_idx
= data_idx
+ 1;
1359 if (ret_data_len
!= 0)
1360 *ret_data_len
= data_len
;
1365 static uint8_t *isis_snmp_find_sys_object(struct variable
*v
, oid
*name
,
1366 size_t *length
, int exact
,
1368 WriteMethod
**write_method
)
1370 struct isis_area
*area
= NULL
;
1371 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1376 if (!list_isempty(isis
->area_list
))
1377 area
= listgetdata(listhead(isis
->area_list
));
1379 /* Check whether the instance identifier is valid */
1380 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
1385 case ISIS_SYS_VERSION
:
1386 return SNMP_INTEGER(ISIS_VERSION
);
1388 case ISIS_SYS_LEVELTYPE
:
1390 * If we do not have areas use 1&2 otherwise use settings
1391 * from the first area in the list
1394 return SNMP_INTEGER(IS_LEVEL_1_AND_2
);
1396 return SNMP_INTEGER(area
->is_type
);
1399 if (!isis
->sysid_set
) {
1400 *var_len
= ISIS_SYS_ID_LEN
;
1401 return isis_null_sysid
;
1404 *var_len
= ISIS_SYS_ID_LEN
;
1407 case ISIS_SYS_MAXPATHSPLITS
:
1408 return SNMP_INTEGER(ISIS_SNMP_MAX_PATH_SPLITS
);
1410 case ISIS_SYS_MAXLSPGENINT
:
1411 return SNMP_INTEGER(DEFAULT_MAX_LSP_GEN_INTERVAL
);
1413 case ISIS_SYS_POLLESHELLORATE
:
1414 return SNMP_INTEGER(DEFAULT_HELLO_INTERVAL
);
1416 case ISIS_SYS_WAITTIME
:
1417 /* Note: it seems that we have same fixed delay time */
1418 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1420 case ISIS_SYS_ADMINSTATE
:
1421 /* If daemon is running it admin state is on */
1422 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
1425 case ISIS_SYS_L2TOL1LEAKING
:
1426 /* We do not allow l2-to-l1 leaking */
1427 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1429 case ISIS_SYS_MAXAGE
:
1430 return SNMP_INTEGER(MAX_AGE
);
1432 case ISIS_SYS_RECEIVELSPBUFFERSIZE
:
1434 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1436 return SNMP_INTEGER(area
->lsp_mtu
);
1438 case ISIS_SYS_PROTSUPPORTED
:
1440 return &isis_snmp_protocols_supported
;
1442 case ISIS_SYS_NOTIFICATIONENABLE
:
1443 if (isis
->snmp_notifications
)
1444 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1446 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1456 static uint8_t *isis_snmp_find_man_area(struct variable
*v
, oid
*name
,
1457 size_t *length
, int exact
,
1459 WriteMethod
**write_method
)
1462 struct area_addr
*area_addr
= NULL
;
1467 *write_method
= NULL
;
1469 if (*length
<= v
->namelen
) {
1472 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1476 oid_idx
= name
+ v
->namelen
;
1477 oid_idx_len
= *length
- v
->namelen
;
1481 res
= isis_snmp_area_addr_lookup_exact(oid_idx
, oid_idx_len
,
1488 res
= isis_snmp_area_addr_lookup_next(oid_idx
, oid_idx_len
,
1494 /* Copy the name out */
1495 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1498 name
[v
->namelen
] = area_addr
->addr_len
;
1500 for (off
= 0; off
< area_addr
->addr_len
; off
++)
1501 name
[v
->namelen
+ 1 + off
] = area_addr
->area_addr
[off
];
1503 *length
= v
->namelen
+ 1 + area_addr
->addr_len
;
1507 case ISIS_MANAREA_ADDREXISTSTATE
:
1508 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
1517 static uint8_t *isis_snmp_find_area_addr(struct variable
*v
, oid
*name
,
1518 size_t *length
, int exact
,
1520 WriteMethod
**write_method
)
1523 * Area addresses in sense of addresses reported by L1 lsps
1524 * are not supported yet.
1533 *write_method
= NULL
;
1538 static uint8_t *isis_snmp_find_summ_addr(struct variable
*v
, oid
*name
,
1539 size_t *length
, int exact
,
1541 WriteMethod
**write_method
)
1544 * So far there is no way to set summary table values through cli
1545 * and snmp operations are read-only, hence there are no entries
1552 *write_method
= NULL
;
1557 static uint8_t *isis_snmp_find_redistribute_addr(struct variable
*v
, oid
*name
,
1558 size_t *length
, int exact
,
1560 WriteMethod
**write_method
)
1563 * It is not clear at the point whether redist code in isis is actually
1564 * used for now we will consider that entries are not present
1571 *write_method
= NULL
;
1576 static uint8_t *isis_snmp_find_router(struct variable
*v
, oid
*name
,
1577 size_t *length
, int exact
,
1579 WriteMethod
**write_method
)
1581 uint8_t cmp_buf
[ISIS_SYS_ID_LEN
];
1586 struct isis_dynhn
*dyn
= NULL
;
1591 *write_method
= NULL
;
1593 if (*length
<= v
->namelen
) {
1596 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1600 oid_idx
= name
+ v
->namelen
;
1601 oid_idx_len
= *length
- v
->namelen
;
1605 res
= isis_snmp_conv_exact(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1606 oid_idx
, oid_idx_len
);
1608 if (!res
|| cmp_len
!= ISIS_SYS_ID_LEN
1609 || oid_idx_len
!= (cmp_len
+ 2))
1611 * Bad conversion, or bad length,
1612 * or extra oids at the end
1616 if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] < IS_LEVEL_1
1617 || oid_idx
[ISIS_SYS_ID_LEN
+ 1] > IS_LEVEL_2
)
1618 /* Level part of the index is out of range */
1621 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1623 dyn
= dynhn_find_by_id(cmp_buf
);
1625 if (dyn
== NULL
|| dyn
->level
!= cmp_level
)
1629 case ISIS_ROUTER_HOSTNAME
:
1630 *var_len
= strlen(dyn
->hostname
);
1631 return (uint8_t *)dyn
->hostname
;
1633 case ISIS_ROUTER_ID
:
1634 /* It seems that we do no know router-id in lsps */
1635 return SNMP_INTEGER(0);
1644 res
= isis_snmp_conv_next(cmp_buf
, sizeof(cmp_buf
), &cmp_len
,
1645 &try_exact
, oid_idx
, oid_idx_len
);
1649 /* Bad conversion */
1652 if (cmp_len
!= ISIS_SYS_ID_LEN
) {
1653 /* We do not have valid index oids */
1654 memset(cmp_buf
, 0, sizeof(cmp_buf
));
1656 } else if (try_exact
)
1658 * We have no valid level index.
1659 * Let start from non-existing level 0 and
1660 * hence not need to do exact match
1663 else if (oid_idx_len
< (ISIS_SYS_ID_LEN
+ 2))
1665 else if (oid_idx
[ISIS_SYS_ID_LEN
+ 1] <= IS_LEVEL_2
)
1666 cmp_level
= (int)oid_idx
[ISIS_SYS_ID_LEN
+ 1];
1669 * Any value greater than 2 will have the same result
1670 * but we can have integer overflows, hence 3 is a reasonable
1673 cmp_level
= (int)(IS_LEVEL_2
+ 1);
1675 dyn
= dynhn_snmp_next(cmp_buf
, cmp_level
);
1680 /* Copy the name out */
1681 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1684 name
[v
->namelen
] = ISIS_SYS_ID_LEN
;
1686 for (off
= 0; off
< ISIS_SYS_ID_LEN
; off
++)
1687 name
[v
->namelen
+ 1 + off
] = dyn
->id
[off
];
1689 name
[v
->namelen
+ 1 + ISIS_SYS_ID_LEN
] = (oid
)dyn
->level
;
1692 *length
= v
->namelen
+ 1 + ISIS_SYS_ID_LEN
+ 1;
1695 case ISIS_ROUTER_HOSTNAME
:
1696 *var_len
= strlen(dyn
->hostname
);
1697 return (uint8_t *)dyn
->hostname
;
1699 case ISIS_ROUTER_ID
:
1700 /* It seems that we do no know router-id in lsps */
1701 return SNMP_INTEGER(0);
1710 static uint8_t *isis_snmp_find_sys_level(struct variable
*v
, oid
*name
,
1711 size_t *length
, int exact
,
1713 WriteMethod
**write_method
)
1719 struct isis_area
*area
= NULL
;
1720 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1725 *write_method
= NULL
;
1727 if (*length
<= v
->namelen
) {
1730 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1734 oid_idx
= name
+ v
->namelen
;
1735 oid_idx_len
= *length
- v
->namelen
;
1739 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1742 if (oid_idx
[0] == IS_LEVEL_1
)
1744 else if (oid_idx
[0] == IS_LEVEL_2
)
1750 if (oid_idx
== NULL
)
1752 else if (oid_idx_len
== 0)
1754 else if (oid_idx
[0] < IS_LEVEL_1
)
1756 else if (oid_idx
[0] < IS_LEVEL_2
)
1761 /* Copy the name out */
1762 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1765 name
[v
->namelen
] = level
;
1768 *length
= v
->namelen
+ 1;
1773 if (!list_isempty(isis
->area_list
))
1774 area
= listgetdata(listhead(isis
->area_list
));
1779 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1782 case ISIS_SYSLEVEL_ORIGLSPBUFFSIZE
:
1784 return SNMP_INTEGER(area
->lsp_mtu
);
1786 return SNMP_INTEGER(DEFAULT_LSP_MTU
);
1788 case ISIS_SYSLEVEL_MINLSPGENINT
:
1790 return SNMP_INTEGER(area
->lsp_gen_interval
[level
- 1]);
1792 return SNMP_INTEGER(DEFAULT_MIN_LSP_GEN_INTERVAL
);
1794 case ISIS_SYSLEVEL_STATE
:
1796 if (area
->overload_bit
)
1797 return SNMP_INTEGER(
1798 ISIS_SNMP_LEVEL_STATE_OVERLOADED
);
1800 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_ON
);
1802 return SNMP_INTEGER(ISIS_SNMP_LEVEL_STATE_OFF
);
1804 case ISIS_SYSLEVEL_SETOVERLOAD
:
1805 if (level_match
&& area
->overload_bit
)
1806 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1808 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1810 case ISIS_SYSLEVEL_SETOVERLOADUNTIL
:
1811 /* We do not have automatic cleanup of overload bit */
1812 return SNMP_INTEGER(0);
1814 case ISIS_SYSLEVEL_METRICSTYLE
:
1816 if (area
->newmetric
&& area
->oldmetric
)
1817 return SNMP_INTEGER(
1818 ISIS_SNMP_METRIC_STYLE_BOTH
);
1820 if (area
->newmetric
)
1821 return SNMP_INTEGER(
1822 ISIS_SNMP_METRIC_STYLE_WIDE
);
1824 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1826 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_NARROW
);
1828 case ISIS_SYSLEVEL_SPFCONSIDERS
:
1829 return SNMP_INTEGER(ISIS_SNMP_METRIC_STYLE_BOTH
);
1831 case ISIS_SYSLEVEL_TEENABLED
:
1832 if (level_match
&& IS_MPLS_TE(area
->mta
))
1833 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
1835 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
1844 static uint8_t *isis_snmp_find_system_counter(struct variable
*v
, oid
*name
,
1845 size_t *length
, int exact
,
1847 WriteMethod
**write_method
)
1853 struct isis_area
*area
= NULL
;
1855 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
1860 *write_method
= NULL
;
1862 if (*length
<= v
->namelen
) {
1865 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
1869 oid_idx
= name
+ v
->namelen
;
1870 oid_idx_len
= *length
- v
->namelen
;
1874 if (oid_idx
== NULL
|| oid_idx_len
!= 1)
1877 if (oid_idx
[0] == IS_LEVEL_1
)
1879 else if (oid_idx
[0] == IS_LEVEL_2
)
1885 if (oid_idx
== NULL
)
1887 else if (oid_idx_len
== 0)
1889 else if (oid_idx
[0] < IS_LEVEL_1
)
1891 else if (oid_idx
[0] < IS_LEVEL_2
)
1896 /* Copy the name out */
1897 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
1900 name
[v
->namelen
] = level
;
1903 *length
= v
->namelen
+ 1;
1908 if (!list_isempty(isis
->area_list
))
1909 area
= listgetdata(listhead(isis
->area_list
));
1914 level_match
= isis_snmp_get_level_match(area
->is_type
, level
);
1917 /* If level does not match all counters are zeros */
1918 return SNMP_INTEGER(0);
1923 case ISIS_SYSSTAT_CORRLSPS
:
1927 case ISIS_SYSSTAT_AUTHTYPEFAILS
:
1928 val
= (uint32_t)area
->auth_type_failures
[level
- 1];
1931 case ISIS_SYSSTAT_AUTHFAILS
:
1932 val
= (uint32_t)area
->auth_failures
[level
- 1];
1935 case ISIS_SYSSTAT_LSPDBASEOLOADS
:
1936 val
= area
->overload_counter
;
1939 case ISIS_SYSSTAT_MANADDRDROPFROMAREAS
:
1940 /* We do not support manual addresses */
1944 case ISIS_SYSSTAT_ATTMPTTOEXMAXSEQNUMS
:
1945 val
= area
->lsp_exceeded_max_counter
;
1948 case ISIS_SYSSTAT_SEQNUMSKIPS
:
1949 val
= area
->lsp_seqno_skipped_counter
;
1952 case ISIS_SYSSTAT_OWNLSPPURGES
:
1953 if (!area
->purge_originator
)
1956 val
= area
->lsp_purge_count
[level
- 1];
1959 case ISIS_SYSSTAT_IDFIELDLENMISMATCHES
:
1960 val
= (uint32_t)area
->id_len_mismatches
[level
- 1];
1963 case ISIS_SYSSTAT_PARTCHANGES
:
1968 case ISIS_SYSSTAT_SPFRUNS
:
1969 val
= (uint32_t)area
->spf_run_count
[level
- 1];
1972 case ISIS_SYSSTAT_LSPERRORS
:
1973 val
= (uint32_t)area
->lsp_error_counter
[level
- 1];
1980 return SNMP_INTEGER(val
);
1983 static uint8_t *isis_snmp_find_next_circ_index(struct variable
*v
, oid
*name
,
1984 size_t *length
, int exact
,
1986 WriteMethod
**write_method
)
1988 /* Check whether the instance identifier is valid */
1989 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
1994 case ISIS_NEXTCIRC_INDEX
:
1996 * We do not support circuit creation through snmp
1998 return SNMP_INTEGER(0);
2007 static uint8_t *isis_snmp_find_circ(struct variable
*v
, oid
*name
,
2008 size_t *length
, int exact
, size_t *var_len
,
2009 WriteMethod
**write_method
)
2011 /* Index is circuit-id: 1-255 */
2014 struct isis_circuit
*circuit
;
2016 uint32_t delta_ticks
;
2020 *write_method
= NULL
;
2022 if (*length
<= v
->namelen
) {
2025 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2029 oid_idx
= name
+ v
->namelen
;
2030 oid_idx_len
= *length
- v
->namelen
;
2033 res
= isis_snmp_circuit_lookup_exact(oid_idx
, oid_idx_len
,
2036 if (!res
|| oid_idx_len
!= 1)
2040 res
= isis_snmp_circuit_lookup_next(oid_idx
, oid_idx_len
,
2046 /* Copy the name out */
2047 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2050 name
[v
->namelen
] = circuit
->snmp_id
;
2053 *length
= v
->namelen
+ 1;
2057 case ISIS_CIRC_IFINDEX
:
2058 if (circuit
->interface
== 0)
2059 return SNMP_INTEGER(0);
2061 return SNMP_INTEGER(circuit
->interface
->ifindex
);
2063 case ISIS_CIRC_ADMINSTATE
:
2064 return SNMP_INTEGER(ISIS_SNMP_ADMIN_STATE_ON
);
2066 case ISIS_CIRC_EXISTSTATE
:
2067 return SNMP_INTEGER(ISIS_SNMP_ROW_STATUS_ACTIVE
);
2069 case ISIS_CIRC_TYPE
:
2071 * Note: values do not match 100%:
2073 * 1. From isis_circuit.h:
2074 * CIRCUIT_T_UNKNOWN 0
2075 * CIRCUIT_T_BROADCAST 1
2077 * CIRCUIT_T_LOOPBACK 3
2086 return SNMP_INTEGER(circuit
->circ_type
);
2088 case ISIS_CIRC_EXTDOMAIN
:
2089 if (circuit
->ext_domain
)
2090 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2092 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2094 case ISIS_CIRC_LEVELTYPE
:
2095 return SNMP_INTEGER(circuit
->is_type
);
2097 case ISIS_CIRC_PASSIVECIRCUIT
:
2098 if (circuit
->is_passive
)
2099 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2101 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2103 case ISIS_CIRC_MESHGROUPENABLED
:
2105 return SNMP_INTEGER(ISIS_SNMP_MESH_GROUP_INACTIVE
);
2107 case ISIS_CIRC_MESHGROUP
:
2109 return SNMP_INTEGER(0);
2111 case ISIS_CIRC_SMALLHELLOS
:
2113 * return false if lan hellos must be padded
2115 if (circuit
->pad_hellos
)
2116 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2118 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_TRUE
);
2120 case ISIS_CIRC_LASTUPTIME
:
2121 if (circuit
->last_uptime
== 0)
2122 return SNMP_INTEGER(0);
2124 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2125 now_time
= isis_snmp_time();
2127 if (circuit
->last_uptime
>= now_time
)
2128 return SNMP_INTEGER(up_ticks
);
2130 delta_ticks
= (now_time
- circuit
->last_uptime
) * 10;
2132 if (up_ticks
< delta_ticks
)
2133 return SNMP_INTEGER(up_ticks
);
2135 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2137 case ISIS_CIRC_3WAYENABLED
:
2139 return SNMP_INTEGER(ISIS_SNMP_TRUTH_VALUE_FALSE
);
2141 case ISIS_CIRC_EXTENDEDCIRCID
:
2142 /* Used for 3-way hand shake only */
2143 return SNMP_INTEGER(0);
2152 static uint8_t *isis_snmp_find_circ_level(struct variable
*v
, oid
*name
,
2153 size_t *length
, int exact
,
2155 WriteMethod
**write_method
)
2157 static uint8_t circuit_id_val
[ISIS_SYS_ID_LEN
+ 1];
2158 /* Index is circuit-id: 1-255 + level: 1-2 */
2162 struct isis_circuit
*circuit
;
2164 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2169 *write_method
= NULL
;
2171 if (*length
<= v
->namelen
) {
2174 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2178 oid_idx
= name
+ v
->namelen
;
2179 oid_idx_len
= *length
- v
->namelen
;
2182 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2183 1, &circuit
, &level
);
2185 if (!res
|| oid_idx_len
!= 2)
2189 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2190 1, &circuit
, &level
);
2195 /* Copy the name out */
2196 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2199 name
[v
->namelen
] = circuit
->snmp_id
;
2200 name
[v
->namelen
+ 1] = level
;
2203 *length
= v
->namelen
+ 2;
2207 case ISIS_CIRCLEVEL_METRIC
:
2208 return SNMP_INTEGER(circuit
->metric
[level
- 1]);
2210 case ISIS_CIRCLEVEL_WIDEMETRIC
:
2211 if (circuit
->area
== NULL
|| !circuit
->area
->newmetric
) {
2212 /* What should we do if wide metric is not supported? */
2213 return SNMP_INTEGER(0);
2215 return SNMP_INTEGER(circuit
->te_metric
[level
- 1]);
2217 case ISIS_CIRCLEVEL_ISPRIORITY
:
2218 return SNMP_INTEGER(circuit
->priority
[level
- 1]);
2220 case ISIS_CIRCLEVEL_IDOCTET
:
2221 return SNMP_INTEGER(circuit
->circuit_id
);
2223 case ISIS_CIRCLEVEL_ID
:
2224 if (circuit
->circ_type
!= CIRCUIT_T_P2P
) {
2226 * Unless it is point-to-point circuit, the value is and
2227 * empty octet string
2230 return circuit_id_val
;
2233 /* !!!!!! Circuit-id is zero for p2p links */
2234 if (circuit
->u
.p2p
.neighbor
== NULL
2235 || circuit
->u
.p2p
.neighbor
->adj_state
!= ISIS_ADJ_UP
) {
2236 /* No adjacency or adjacency not fully up yet */
2237 memcpy(circuit_id_val
, isis
->sysid
, ISIS_SYS_ID_LEN
);
2238 circuit_id_val
[ISIS_SYS_ID_LEN
] = circuit
->circuit_id
;
2239 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2240 return circuit_id_val
;
2243 /* Adjacency fully-up */
2244 memcpy(circuit_id_val
, circuit
->u
.p2p
.neighbor
->sysid
,
2246 circuit_id_val
[ISIS_SYS_ID_LEN
] = 0;
2247 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2248 return circuit_id_val
;
2250 case ISIS_CIRCLEVEL_DESIS
:
2251 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
2252 || !circuit
->u
.bc
.is_dr
[level
- 1]) {
2254 * Unless it is lan circuit participating in dis process
2255 * the value is an empty octet string
2258 return circuit_id_val
;
2261 *var_len
= ISIS_SYS_ID_LEN
+ 1;
2263 if (level
== IS_LEVEL_1
)
2264 return circuit
->u
.bc
.l1_desig_is
;
2266 return circuit
->u
.bc
.l2_desig_is
;
2268 case ISIS_CIRCLEVEL_HELLOMULTIPLIER
:
2269 return SNMP_INTEGER(circuit
->hello_multiplier
[level
- 1]);
2271 case ISIS_CIRCLEVEL_HELLOTIMER
:
2272 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2274 case ISIS_CIRCLEVEL_DRHELLOTIMER
:
2275 return SNMP_INTEGER(circuit
->hello_interval
[level
- 1] * 1000);
2277 case ISIS_CIRCLEVEL_LSPTHROTTLE
:
2279 return SNMP_INTEGER(
2280 circuit
->area
->min_spf_interval
[level
- 1]
2283 return SNMP_INTEGER(0);
2285 case ISIS_CIRCLEVEL_MINLSPRETRANSINT
:
2287 return SNMP_INTEGER(
2288 circuit
->area
->min_spf_interval
[level
- 1]);
2290 return SNMP_INTEGER(0);
2292 case ISIS_CIRCLEVEL_CSNPINTERVAL
:
2293 return SNMP_INTEGER(circuit
->csnp_interval
[level
- 1]);
2295 case ISIS_CIRCLEVEL_PARTSNPINTERVAL
:
2296 return SNMP_INTEGER(circuit
->psnp_interval
[level
- 1]);
2305 static uint8_t *isis_snmp_find_circ_counter(struct variable
*v
, oid
*name
,
2306 size_t *length
, int exact
,
2308 WriteMethod
**write_method
)
2310 /* Index circuit-id 1-255 + level */
2314 struct isis_circuit
*circuit
;
2318 *write_method
= NULL
;
2320 if (*length
<= v
->namelen
) {
2323 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2327 oid_idx
= name
+ v
->namelen
;
2328 oid_idx_len
= *length
- v
->namelen
;
2331 res
= isis_snmp_circuit_level_lookup_exact(oid_idx
, oid_idx_len
,
2332 1, &circuit
, &level
);
2334 if (!res
|| oid_idx_len
!= 2)
2338 res
= isis_snmp_circuit_level_lookup_next(oid_idx
, oid_idx_len
,
2339 1, &circuit
, &level
);
2344 /* Copy the name out */
2345 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2348 name
[v
->namelen
] = circuit
->snmp_id
;
2349 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2350 name
[v
->namelen
+ 1] = ISIS_SNMP_P2P_CIRCUIT
;
2352 name
[v
->namelen
+ 1] = level
;
2355 *length
= v
->namelen
+ 2;
2359 case ISIS_CIRC_ADJCHANGES
:
2360 val
= circuit
->adj_state_changes
;
2363 case ISIS_CIRC_NUMADJ
:
2364 if (circuit
->circ_type
== CIRCUIT_T_P2P
) {
2365 val
= circuit
->u
.p2p
.neighbor
== NULL
? 0 : 1;
2369 if (circuit
->circ_type
!= CIRCUIT_T_BROADCAST
) {
2374 if (level
== IS_LEVEL_1
) {
2375 if (circuit
->u
.bc
.adjdb
[0] == NULL
)
2378 val
= listcount(circuit
->u
.bc
.adjdb
[0]);
2382 if (circuit
->u
.bc
.adjdb
[1] == NULL
)
2385 val
= listcount(circuit
->u
.bc
.adjdb
[1]);
2389 case ISIS_CIRC_INITFAILS
:
2390 val
= circuit
->init_failures
; /* counter never incremented */
2393 case ISIS_CIRC_REJADJS
:
2394 val
= circuit
->rej_adjacencies
;
2397 case ISIS_CIRC_IDFIELDLENMISMATCHES
:
2398 val
= circuit
->id_len_mismatches
;
2401 case ISIS_CIRC_MAXAREAADDRMISMATCHES
:
2402 val
= circuit
->max_area_addr_mismatches
;
2405 case ISIS_CIRC_AUTHTYPEFAILS
:
2406 val
= circuit
->auth_type_failures
;
2409 case ISIS_CIRC_AUTHFAILS
:
2410 val
= circuit
->auth_failures
;
2413 case ISIS_CIRC_LANDESISCHANGES
:
2414 if (circuit
->circ_type
== CIRCUIT_T_P2P
)
2417 val
= circuit
->desig_changes
[level
- 1];
2424 return SNMP_INTEGER(val
);
2427 static uint8_t *isis_snmp_find_isadj(struct variable
*v
, oid
*name
,
2428 size_t *length
, int exact
, size_t *var_len
,
2429 WriteMethod
**write_method
)
2431 /* Index is circuit-id: 1-255 + adj-id: 1-... */
2436 struct isis_adjacency
*adj
;
2438 uint32_t delta_ticks
;
2441 *write_method
= NULL
;
2443 if (*length
<= v
->namelen
) {
2446 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2450 oid_idx
= name
+ v
->namelen
;
2451 oid_idx_len
= *length
- v
->namelen
;
2454 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2455 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2458 if (!res
|| oid_idx_len
!= 2)
2462 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2463 ISIS_SNMP_ADJ_DATA_NONE
, &adj
,
2468 /* Copy the name out */
2469 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2472 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2473 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2476 *length
= v
->namelen
+ 2;
2480 case ISIS_ISADJ_STATE
:
2481 val
= ISIS_SNMP_ADJ_STATE_DOWN
;
2483 switch (adj
->adj_state
) {
2484 case ISIS_ADJ_UNKNOWN
:
2486 val
= ISIS_SNMP_ADJ_STATE_DOWN
;
2489 case ISIS_ADJ_INITIALIZING
:
2490 val
= ISIS_SNMP_ADJ_STATE_INITIALIZING
;
2494 val
= ISIS_SNMP_ADJ_STATE_UP
;
2498 return SNMP_INTEGER(val
);
2500 case ISIS_ISADJ_3WAYSTATE
:
2501 return SNMP_INTEGER(adj
->threeway_state
);
2503 case ISIS_ISADJ_NEIGHSNPAADDRESS
: {
2504 const char *snpa
= (char *)snpa_print(adj
->snpa
);
2505 *var_len
= strlen(snpa
);
2506 return (uint8_t *)snpa
;
2509 case ISIS_ISADJ_NEIGHSYSTYPE
:
2510 val
= ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN
;
2512 switch (adj
->sys_type
) {
2513 case ISIS_SYSTYPE_UNKNOWN
:
2514 case ISIS_SYSTYPE_ES
:
2515 val
= ISIS_SNMP_ADJ_NEIGHTYPE_UNKNOWN
;
2518 case ISIS_SYSTYPE_IS
:
2519 val
= ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1_L2
;
2522 case ISIS_SYSTYPE_L1_IS
:
2523 val
= ISIS_SNMP_ADJ_NEIGHTYPE_IS_L1
;
2526 case ISIS_SYSTYPE_L2_IS
:
2527 val
= ISIS_SNMP_ADJ_NEIGHTYPE_IS_L2
;
2531 return SNMP_INTEGER(val
);
2533 case ISIS_ISADJ_NEIGHSYSID
:
2534 *var_len
= sizeof(adj
->sysid
);
2537 case ISIS_ISADJ_NBREXTENDEDCIRCID
:
2538 return SNMP_INTEGER(adj
->ext_circuit_id
!= 0 ? 1 : 0);
2540 case ISIS_ISADJ_USAGE
:
2541 /* It seems that no value conversion is required */
2542 return SNMP_INTEGER(adj
->adj_usage
);
2544 case ISIS_ISADJ_HOLDTIMER
:
2546 * It seems that we want remaining timer
2548 if (adj
->last_upd
!= 0) {
2549 val
= isis_snmp_time();
2550 if (val
< (adj
->last_upd
+ adj
->hold_time
))
2551 return SNMP_INTEGER(adj
->last_upd
2552 + adj
->hold_time
- val
);
2554 /* Not running or just expired */
2555 return SNMP_INTEGER(0);
2557 case ISIS_ISADJ_NEIGHPRIORITY
:
2558 return SNMP_INTEGER(adj
->prio
[adj
->level
- 1]);
2560 case ISIS_ISADJ_LASTUPTIME
:
2561 if (adj
->flaps
== 0)
2562 return SNMP_INTEGER(0);
2564 up_ticks
= (uint32_t)netsnmp_get_agent_uptime();
2566 now_time
= isis_snmp_time();
2568 if (adj
->last_flap
>= now_time
)
2569 return SNMP_INTEGER(up_ticks
);
2571 delta_ticks
= (now_time
- adj
->last_flap
) * 10;
2573 if (up_ticks
< delta_ticks
)
2574 return SNMP_INTEGER(up_ticks
);
2576 return SNMP_INTEGER(up_ticks
- delta_ticks
);
2585 static uint8_t *isis_snmp_find_isadj_area(struct variable
*v
, oid
*name
,
2586 size_t *length
, int exact
,
2588 WriteMethod
**write_method
)
2590 /* Index circuit-id: 1-255 + adj-id: 1-... */
2594 struct isis_adjacency
*adj
;
2599 *write_method
= NULL
;
2601 if (*length
<= v
->namelen
) {
2604 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2608 oid_idx
= name
+ v
->namelen
;
2609 oid_idx_len
= *length
- v
->namelen
;
2612 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2613 ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2614 &adj
, NULL
, &data
, &data_len
);
2616 if (!res
|| oid_idx_len
!= 3)
2620 res
= isis_snmp_adj_lookup_next(
2621 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_AREA_ADDR
,
2622 &adj
, &data_idx
, &data
, &data_len
);
2626 /* Copy the name out */
2627 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2630 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2631 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2632 name
[v
->namelen
+ 2] = data_idx
;
2635 *length
= v
->namelen
+ 3;
2639 case ISIS_ISADJAREA_ADDRESS
:
2640 *var_len
= data_len
;
2650 static uint8_t *isis_snmp_find_isadj_ipaddr(struct variable
*v
, oid
*name
,
2651 size_t *length
, int exact
,
2653 WriteMethod
**write_method
)
2655 /* Index circuit-id 1-255 + adj-id 1-... */
2659 struct isis_adjacency
*adj
;
2664 *write_method
= NULL
;
2666 if (*length
<= v
->namelen
) {
2669 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2673 oid_idx
= name
+ v
->namelen
;
2674 oid_idx_len
= *length
- v
->namelen
;
2677 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2678 ISIS_SNMP_ADJ_DATA_IP_ADDR
,
2679 &adj
, NULL
, &data
, &data_len
);
2681 if (!res
|| oid_idx_len
!= 3)
2684 res
= isis_snmp_adj_lookup_next(
2685 oid_idx
, oid_idx_len
, ISIS_SNMP_ADJ_DATA_IP_ADDR
, &adj
,
2686 &data_idx
, &data
, &data_len
);
2690 /* Copy the name out */
2691 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2694 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2695 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2696 name
[v
->namelen
+ 2] = data_idx
;
2699 *length
= v
->namelen
+ 3;
2703 case ISIS_ISADJIPADDR_TYPE
:
2705 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V4
);
2707 return SNMP_INTEGER(ISIS_SNMP_INET_TYPE_V6
);
2709 case ISIS_ISADJIPADDR_ADDRESS
:
2710 *var_len
= data_len
;
2720 static uint8_t *isis_snmp_find_isadj_prot_supp(struct variable
*v
, oid
*name
,
2721 size_t *length
, int exact
,
2723 WriteMethod
**write_method
)
2725 /* Index circuit-id 1-255 + adj-id 1-... */
2729 struct isis_adjacency
*adj
;
2734 *write_method
= NULL
;
2736 if (*length
<= v
->namelen
) {
2739 } else if (memcmp(name
, v
->name
, v
->namelen
* sizeof(oid
)) != 0) {
2743 oid_idx
= name
+ v
->namelen
;
2744 oid_idx_len
= *length
- v
->namelen
;
2747 res
= isis_snmp_adj_lookup_exact(oid_idx
, oid_idx_len
,
2748 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2749 NULL
, &data
, &data_len
);
2751 if (!res
|| oid_idx_len
!= 3)
2755 res
= isis_snmp_adj_lookup_next(oid_idx
, oid_idx_len
,
2756 ISIS_SNMP_ADJ_DATA_PROTO
, &adj
,
2757 &data_idx
, &data
, &data_len
);
2761 /* Copy the name out */
2762 memcpy(name
, v
->name
, v
->namelen
* sizeof(oid
));
2765 name
[v
->namelen
] = adj
->circuit
->snmp_id
;
2766 name
[v
->namelen
+ 1] = adj
->snmp_idx
;
2767 name
[v
->namelen
+ 2] = data_idx
;
2770 *length
= v
->namelen
+ 3;
2774 case ISIS_ISADJPROTSUPP_PROTOCOL
:
2775 return SNMP_INTEGER(*data
);
2785 /* Register ISIS-MIB. */
2786 static int isis_snmp_init(struct thread_master
*tm
)
2788 struct isis_func_to_prefix
*h2f
= isis_func_to_prefix_arr
;
2791 for (size_t off
= 0; off
< isis_var_count
; off
++) {
2792 v
= &isis_var_arr
[off
];
2794 if (v
->findVar
!= h2f
->ihtp_func
) {
2797 assert(h2f
< (isis_func_to_prefix_arr
2798 + isis_func_to_prefix_count
));
2799 assert(v
->findVar
== h2f
->ihtp_func
);
2802 v
->namelen
= h2f
->ihtp_pref_len
+ 1;
2803 memcpy(v
->name
, h2f
->ihtp_pref_oid
,
2804 h2f
->ihtp_pref_len
* sizeof(oid
));
2805 v
->name
[h2f
->ihtp_pref_len
] = v
->magic
;
2810 REGISTER_MIB("mibII/isis", isis_var_arr
, variable
, isis_oid
);
2815 * ISIS notification functions: we have one function per notification
2817 static int isis_snmp_trap_throttle(oid trap_id
)
2820 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
2822 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
2825 time_now
= isis_snmp_time();
2827 if ((isis_snmp_trap_timestamp
[trap_id
] + 5) > time_now
)
2828 /* Throttle trap rate at 1 in 5 secs */
2831 isis_snmp_trap_timestamp
[trap_id
] = time_now
;
2835 static int isis_snmp_db_overload_update(const struct isis_area
*area
)
2837 netsnmp_variable_list
*notification_vars
;
2841 if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD
))
2844 notification_vars
= NULL
;
2846 /* Put in trap value */
2847 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2848 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2849 (uint8_t *)&isis_snmp_trap_val_db_overload
,
2850 sizeof(isis_snmp_trap_val_db_overload
));
2853 val
= area
->is_type
;
2855 snmp_varlist_add_variable(
2856 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2857 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2858 (uint8_t *)&val
, sizeof(val
));
2860 /* Patch sys_level_state with proper index */
2861 off
= ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
) - 1;
2862 isis_snmp_trap_data_var_sys_level_state
[off
] = val
;
2865 if (area
->overload_bit
)
2866 val
= ISIS_SNMP_LEVEL_STATE_OVERLOADED
;
2868 val
= ISIS_SNMP_LEVEL_STATE_ON
;
2870 snmp_varlist_add_variable(
2871 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_state
,
2872 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state
), INTEGER
,
2873 (uint8_t *)&val
, sizeof(val
));
2875 send_v2trap(notification_vars
);
2876 snmp_free_varbind(notification_vars
);
2877 smux_events_update();
2881 static int isis_snmp_lsp_exceed_max_update(const struct isis_area
*area
,
2882 const uint8_t *lsp_id
)
2884 netsnmp_variable_list
*notification_vars
;
2887 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_EXCEED_MAX
))
2890 notification_vars
= NULL
;
2892 /* Put in trap value */
2893 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2894 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2895 (uint8_t *)&isis_snmp_trap_val_lsp_exceed_max
,
2896 sizeof(isis_snmp_trap_val_lsp_exceed_max
));
2899 val
= area
->is_type
;
2901 snmp_varlist_add_variable(
2902 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2903 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2904 (uint8_t *)&val
, sizeof(val
));
2906 snmp_varlist_add_variable(
2907 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
2908 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
2909 ISIS_SYS_ID_LEN
+ 2);
2911 send_v2trap(notification_vars
);
2912 snmp_free_varbind(notification_vars
);
2913 smux_events_update();
2919 * A common function to handle popular combination of trap objects
2920 * isisNotificationSysLevelIndex,
2922 * isisNotificationCircIfIndex,
2925 static void isis_snmp_update_worker_a(const struct isis_circuit
*circuit
,
2926 oid trap_id
, const oid
*oid_a
,
2927 size_t oid_a_len
, uint8_t type_a
,
2928 const void *data_a
, size_t data_a_len
,
2929 const oid
*oid_b
, size_t oid_b_len
,
2930 uint8_t type_b
, const void *data_b
,
2933 netsnmp_variable_list
*notification_vars
= NULL
;
2934 oid var_name
[MAX_OID_LEN
];
2939 if (trap_id
!= ISIS_TRAP_ID_LEN_MISMATCH
2940 && trap_id
!= ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
2941 && trap_id
!= ISIS_TRAP_OWN_LSP_PURGE
2942 && trap_id
!= ISIS_TRAP_SEQNO_SKIPPED
2943 && trap_id
!= ISIS_TRAP_AUTHEN_TYPE_FAILURE
2944 && trap_id
!= ISIS_TRAP_AUTHEN_FAILURE
2945 && trap_id
!= ISIS_TRAP_REJ_ADJACENCY
)
2948 /* Put in trap value */
2949 memcpy(var_name
, isis_snmp_notifications
,
2950 sizeof(isis_snmp_notifications
));
2951 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
2952 var_name
[var_count
++] = trap_id
;
2954 /* Put in trap value */
2955 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
2956 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
2957 (uint8_t *)var_name
, var_count
* sizeof(oid
));
2959 val
= circuit
->is_type
;
2960 snmp_varlist_add_variable(
2961 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
2962 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
2963 (uint8_t *)&val
, sizeof(val
));
2965 if (oid_a_len
!= 0) {
2966 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
2969 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
2970 type_a
, (uint8_t *)data_a
,
2974 if (circuit
->interface
== NULL
)
2977 val
= circuit
->interface
->ifindex
;
2979 snmp_varlist_add_variable(
2980 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
2981 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
2982 (uint8_t *)&val
, sizeof(val
));
2985 if (oid_b_len
!= 0) {
2986 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
2989 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
2990 type_b
, (uint8_t *)data_b
,
2994 send_v2trap(notification_vars
);
2995 snmp_free_varbind(notification_vars
);
2996 smux_events_update();
3000 * A common function to handle popular combination of trap objects
3001 * isisNotificationSysLevelIndex,
3002 * isisNotificationCircIfIndex,
3006 * Note: the only difference with worker_a is order of circ-if-index vs
3009 static void isis_snmp_update_worker_b(const struct isis_circuit
*circuit
,
3010 oid trap_id
, const oid
*oid_a
,
3011 size_t oid_a_len
, uint8_t type_a
,
3012 const void *data_a
, size_t data_a_len
,
3013 const oid
*oid_b
, size_t oid_b_len
,
3014 uint8_t type_b
, const void *data_b
,
3017 netsnmp_variable_list
*notification_vars
= NULL
;
3018 oid var_name
[MAX_OID_LEN
];
3023 if (trap_id
!= ISIS_TRAP_VERSION_SKEW
3024 && trap_id
!= ISIS_TRAP_LSP_TOO_LARGE
3025 && trap_id
!= ISIS_TRAP_ADJ_STATE_CHANGE
)
3028 /* Put in trap value */
3029 memcpy(var_name
, isis_snmp_notifications
,
3030 sizeof(isis_snmp_notifications
));
3031 var_count
= ARRAY_SIZE(isis_snmp_notifications
);
3032 var_name
[var_count
++] = trap_id
;
3034 /* Put in trap value */
3035 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3036 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3037 (uint8_t *)var_name
, var_count
* sizeof(oid
));
3039 val
= circuit
->is_type
;
3040 snmp_varlist_add_variable(
3041 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3042 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3043 (uint8_t *)&val
, sizeof(val
));
3045 if (circuit
->interface
== NULL
)
3048 val
= circuit
->interface
->ifindex
;
3050 snmp_varlist_add_variable(
3051 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3052 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3053 (uint8_t *)&val
, sizeof(val
));
3056 if (oid_a_len
!= 0) {
3057 if (oid_a
== NULL
|| data_a
== NULL
|| data_a_len
== 0)
3060 snmp_varlist_add_variable(¬ification_vars
, oid_a
, oid_a_len
,
3061 type_a
, (uint8_t *)data_a
,
3065 if (oid_b_len
!= 0) {
3066 if (oid_b
== NULL
|| data_b
== NULL
|| data_b_len
== 0)
3069 snmp_varlist_add_variable(¬ification_vars
, oid_b
, oid_b_len
,
3070 type_b
, (uint8_t *)data_b
,
3074 send_v2trap(notification_vars
);
3075 snmp_free_varbind(notification_vars
);
3076 smux_events_update();
3080 static int isis_snmp_id_len_mismatch_update(const struct isis_circuit
*circuit
,
3081 uint8_t rcv_id
, const char *raw_pdu
,
3086 if (!isis_snmp_trap_throttle(ISIS_TRAP_ID_LEN_MISMATCH
))
3091 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3092 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3094 isis_snmp_update_worker_a(
3095 circuit
, ISIS_TRAP_ID_LEN_MISMATCH
,
3096 isis_snmp_trap_data_var_pdu_field_len
,
3097 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_field_len
), UNSIGNED32
,
3098 &val
, sizeof(val
), isis_snmp_trap_data_var_pdu_fragment
,
3099 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3100 raw_pdu
, raw_pdu_len
);
3105 isis_snmp_max_area_addr_mismatch_update(const struct isis_circuit
*circuit
,
3106 uint8_t max_addrs
, const char *raw_pdu
,
3111 if (!isis_snmp_trap_throttle(ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
))
3116 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3117 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3119 isis_snmp_update_worker_a(
3120 circuit
, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH
,
3121 isis_snmp_trap_data_var_pdu_max_area_addr
,
3122 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_max_area_addr
),
3123 UNSIGNED32
, &val
, sizeof(val
),
3124 isis_snmp_trap_data_var_pdu_fragment
,
3125 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3126 raw_pdu
, raw_pdu_len
);
3130 static int isis_snmp_own_lsp_purge_update(const struct isis_circuit
*circuit
,
3131 const uint8_t *lsp_id
)
3133 if (!isis_snmp_trap_throttle(ISIS_TRAP_OWN_LSP_PURGE
))
3136 isis_snmp_update_worker_a(
3137 circuit
, ISIS_TRAP_OWN_LSP_PURGE
, NULL
, 0, STRING
, NULL
, 0,
3138 isis_snmp_trap_data_var_pdu_lsp_id
,
3139 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3140 ISIS_SYS_ID_LEN
+ 2);
3144 static int isis_snmp_seqno_skipped_update(const struct isis_circuit
*circuit
,
3145 const uint8_t *lsp_id
)
3147 if (!isis_snmp_trap_throttle(ISIS_TRAP_SEQNO_SKIPPED
))
3150 isis_snmp_update_worker_a(
3151 circuit
, ISIS_TRAP_SEQNO_SKIPPED
, NULL
, 0, STRING
, NULL
, 0,
3152 isis_snmp_trap_data_var_pdu_lsp_id
,
3153 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3154 ISIS_SYS_ID_LEN
+ 2);
3159 isis_snmp_authentication_type_failure_update(const struct isis_circuit
*circuit
,
3160 const char *raw_pdu
,
3163 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_TYPE_FAILURE
))
3166 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3167 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3169 isis_snmp_update_worker_a(
3170 circuit
, ISIS_TRAP_AUTHEN_TYPE_FAILURE
, NULL
, 0, STRING
, NULL
,
3171 0, isis_snmp_trap_data_var_pdu_fragment
,
3172 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3173 raw_pdu
, raw_pdu_len
);
3178 isis_snmp_authentication_failure_update(const struct isis_circuit
*circuit
,
3179 char const *raw_pdu
, size_t raw_pdu_len
)
3181 if (!isis_snmp_trap_throttle(ISIS_TRAP_AUTHEN_FAILURE
))
3184 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3185 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3187 isis_snmp_update_worker_a(
3188 circuit
, ISIS_TRAP_AUTHEN_FAILURE
, NULL
, 0, STRING
, NULL
, 0,
3189 isis_snmp_trap_data_var_pdu_fragment
,
3190 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3191 raw_pdu
, raw_pdu_len
);
3195 static int isis_snmp_version_skew_update(const struct isis_circuit
*circuit
,
3196 uint8_t version
, const char *raw_pdu
,
3201 if (!isis_snmp_trap_throttle(ISIS_TRAP_VERSION_SKEW
))
3206 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3207 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3209 isis_snmp_update_worker_b(
3210 circuit
, ISIS_TRAP_VERSION_SKEW
,
3211 isis_snmp_trap_data_var_pdu_proto_ver
,
3212 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_proto_ver
), UNSIGNED32
,
3213 &val
, sizeof(val
), 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_area_mismatch_update(const struct isis_circuit
*circuit
,
3220 const char *raw_pdu
,
3224 * This is a special case because
3225 * it does not include isisNotificationSysLevelIndex
3227 netsnmp_variable_list
*notification_vars
;
3230 if (!isis_snmp_trap_throttle(ISIS_TRAP_AREA_MISMATCH
))
3233 notification_vars
= NULL
;
3235 /* Put in trap value */
3236 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3237 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3238 (uint8_t *)&isis_snmp_trap_val_area_mismatch
,
3239 sizeof(isis_snmp_trap_val_area_mismatch
));
3242 if (circuit
->interface
== NULL
)
3245 val
= circuit
->interface
->ifindex
;
3247 snmp_varlist_add_variable(
3248 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3249 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3250 (uint8_t *)&val
, sizeof(val
));
3253 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3254 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3256 snmp_varlist_add_variable(
3257 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3258 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3259 raw_pdu
, raw_pdu_len
);
3261 send_v2trap(notification_vars
);
3262 snmp_free_varbind(notification_vars
);
3263 smux_events_update();
3268 static int isis_snmp_reject_adjacency_update(const struct isis_circuit
*circuit
,
3269 const char *raw_pdu
,
3272 if (!isis_snmp_trap_throttle(ISIS_TRAP_REJ_ADJACENCY
))
3275 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3276 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3278 isis_snmp_update_worker_a(
3279 circuit
, ISIS_TRAP_REJ_ADJACENCY
, NULL
, 0, STRING
, NULL
, 0,
3280 isis_snmp_trap_data_var_pdu_fragment
,
3281 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3282 raw_pdu
, raw_pdu_len
);
3286 static int isis_snmp_lsp_too_large_update(const struct isis_circuit
*circuit
,
3288 const uint8_t *lsp_id
)
3290 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_TOO_LARGE
))
3293 isis_snmp_update_worker_b(
3294 circuit
, ISIS_TRAP_LSP_TOO_LARGE
,
3295 isis_snmp_trap_data_var_pdu_lsp_size
,
3296 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_size
), UNSIGNED32
,
3297 &pdu_size
, sizeof(pdu_size
), isis_snmp_trap_data_var_pdu_lsp_id
,
3298 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3299 ISIS_SYS_ID_LEN
+ 2);
3304 static int isis_snmp_adj_state_change_update(const struct isis_adjacency
*adj
)
3306 uint8_t lsp_id
[ISIS_SYS_ID_LEN
+ 2];
3308 struct isis
*isis
= isis_lookup_by_vrfid(VRF_DEFAULT
);
3310 if (isis
== NULL
|| !isis
->snmp_notifications
|| !smux_enabled())
3314 memcpy(lsp_id
, adj
->sysid
, ISIS_SYS_ID_LEN
);
3315 lsp_id
[ISIS_SYS_ID_LEN
] = 0;
3316 lsp_id
[ISIS_SYS_ID_LEN
+ 1] = 0;
3318 val
= ISIS_SNMP_ADJ_STATE_DOWN
;
3320 switch (adj
->adj_state
) {
3321 case ISIS_ADJ_UNKNOWN
:
3322 val
= ISIS_SNMP_ADJ_STATE_DOWN
;
3325 case ISIS_ADJ_INITIALIZING
:
3326 val
= ISIS_SNMP_ADJ_STATE_INITIALIZING
;
3330 val
= ISIS_SNMP_ADJ_STATE_UP
;
3334 val
= ISIS_SNMP_ADJ_STATE_FAILED
;
3338 isis_snmp_update_worker_b(
3339 adj
->circuit
, ISIS_TRAP_ADJ_STATE_CHANGE
,
3340 isis_snmp_trap_data_var_pdu_lsp_id
,
3341 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3342 ISIS_SYS_ID_LEN
+ 2, isis_snmp_trap_data_var_adj_state
,
3343 ARRAY_SIZE(isis_snmp_trap_data_var_adj_state
), INTEGER
, &val
,
3348 static int isis_snmp_lsp_error_update(const struct isis_circuit
*circuit
,
3349 const uint8_t *lsp_id
,
3350 char const *raw_pdu
, size_t raw_pdu_len
)
3353 * This is a special case because
3354 * it have more variables
3356 netsnmp_variable_list
*notification_vars
;
3359 if (!isis_snmp_trap_throttle(ISIS_TRAP_LSP_ERROR
))
3362 notification_vars
= NULL
;
3364 /* Put in trap value */
3365 snmp_varlist_add_variable(¬ification_vars
, isis_snmp_trap_var
,
3366 ARRAY_SIZE(isis_snmp_trap_var
), ASN_OBJECT_ID
,
3367 (uint8_t *)&isis_snmp_trap_val_lsp_error
,
3368 sizeof(isis_snmp_trap_val_lsp_error
));
3371 val
= circuit
->is_type
;
3373 snmp_varlist_add_variable(
3374 ¬ification_vars
, isis_snmp_trap_data_var_sys_level_index
,
3375 ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index
), INTEGER
,
3376 (uint8_t *)&val
, sizeof(val
));
3379 snmp_varlist_add_variable(
3380 ¬ification_vars
, isis_snmp_trap_data_var_pdu_lsp_id
,
3381 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id
), STRING
, lsp_id
,
3382 ISIS_SYS_ID_LEN
+ 2);
3385 if (circuit
->interface
== NULL
)
3388 val
= circuit
->interface
->ifindex
;
3390 snmp_varlist_add_variable(
3391 ¬ification_vars
, isis_snmp_trap_data_var_circ_if_index
,
3392 ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index
), UNSIGNED32
,
3393 (uint8_t *)&val
, sizeof(val
));
3396 if (raw_pdu_len
> ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
)
3397 raw_pdu_len
= ISIS_SNMP_TRAP_PDU_FRAGMENT_MAX_LEN
;
3399 snmp_varlist_add_variable(
3400 ¬ification_vars
, isis_snmp_trap_data_var_pdu_fragment
,
3401 ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment
), STRING
,
3402 raw_pdu
, raw_pdu_len
);
3407 snmp_varlist_add_variable(
3408 ¬ification_vars
, isis_snmp_trap_data_var_error_offset
,
3409 ARRAY_SIZE(isis_snmp_trap_data_var_error_offset
), UNSIGNED32
,
3410 (uint8_t *)&val
, sizeof(val
));
3415 snmp_varlist_add_variable(
3416 ¬ification_vars
, isis_snmp_trap_data_var_error_tlv_type
,
3417 ARRAY_SIZE(isis_snmp_trap_data_var_error_tlv_type
), UNSIGNED32
,
3418 (uint8_t *)&val
, sizeof(val
));
3420 send_v2trap(notification_vars
);
3421 snmp_free_varbind(notification_vars
);
3422 smux_events_update();
3427 static int isis_snmp_module_init(void)
3429 hook_register(isis_hook_db_overload
, isis_snmp_db_overload_update
);
3430 hook_register(isis_hook_lsp_exceed_max
,
3431 isis_snmp_lsp_exceed_max_update
);
3432 hook_register(isis_hook_id_len_mismatch
,
3433 isis_snmp_id_len_mismatch_update
);
3434 hook_register(isis_hook_max_area_addr_mismatch
,
3435 isis_snmp_max_area_addr_mismatch_update
);
3436 hook_register(isis_hook_own_lsp_purge
, isis_snmp_own_lsp_purge_update
);
3437 hook_register(isis_hook_seqno_skipped
, isis_snmp_seqno_skipped_update
);
3438 hook_register(isis_hook_authentication_type_failure
,
3439 isis_snmp_authentication_type_failure_update
);
3440 hook_register(isis_hook_authentication_failure
,
3441 isis_snmp_authentication_failure_update
);
3442 hook_register(isis_hook_version_skew
, isis_snmp_version_skew_update
);
3443 hook_register(isis_hook_area_mismatch
, isis_snmp_area_mismatch_update
);
3444 hook_register(isis_hook_reject_adjacency
,
3445 isis_snmp_reject_adjacency_update
);
3446 hook_register(isis_hook_lsp_too_large
, isis_snmp_lsp_too_large_update
);
3447 hook_register(isis_hook_adj_state_change
,
3448 isis_snmp_adj_state_change_update
);
3449 hook_register(isis_hook_lsp_error
, isis_snmp_lsp_error_update
);
3451 hook_register(frr_late_init
, isis_snmp_init
);
3456 .name
= "isis_snmp",
3457 .version
= FRR_VERSION
,
3458 .description
= "isis AgentX SNMP module",
3459 .init
= isis_snmp_module_init
,