1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
4 * Copyright (C) 2000 IP Infusion Inc.
6 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
11 #include <net-snmp/net-snmp-config.h>
12 #include <net-snmp/net-snmp-includes.h>
22 #include "lib/version.h"
24 #include "ospfd/ospfd.h"
25 #include "ospfd/ospf_interface.h"
26 #include "ospfd/ospf_asbr.h"
27 #include "ospfd/ospf_lsa.h"
28 #include "ospfd/ospf_lsdb.h"
29 #include "ospfd/ospf_abr.h"
30 #include "ospfd/ospf_neighbor.h"
31 #include "ospfd/ospf_nsm.h"
32 #include "ospfd/ospf_flood.h"
33 #include "ospfd/ospf_ism.h"
34 #include "ospfd/ospf_dump.h"
35 #include "ospfd/ospf_route.h"
36 #include "ospfd/ospf_zebra.h"
38 DEFINE_MTYPE_STATIC(OSPFD
, SNMP
, "OSPF SNMP");
41 #define OSPF2MIB 1,3,6,1,2,1,14
43 /* OSPF MIB General Group values. */
44 #define OSPFROUTERID 1
45 #define OSPFADMINSTAT 2
46 #define OSPFVERSIONNUMBER 3
47 #define OSPFAREABDRRTRSTATUS 4
48 #define OSPFASBDRRTRSTATUS 5
49 #define OSPFEXTERNLSACOUNT 6
50 #define OSPFEXTERNLSACKSUMSUM 7
51 #define OSPFTOSSUPPORT 8
52 #define OSPFORIGINATENEWLSAS 9
53 #define OSPFRXNEWLSAS 10
54 #define OSPFEXTLSDBLIMIT 11
55 #define OSPFMULTICASTEXTENSIONS 12
56 #define OSPFEXITOVERFLOWINTERVAL 13
57 #define OSPFDEMANDEXTENSIONS 14
59 /* OSPF MIB ospfAreaTable. */
61 #define OSPFAUTHTYPE 2
62 #define OSPFIMPORTASEXTERN 3
64 #define OSPFAREABDRRTRCOUNT 5
65 #define OSPFASBDRRTRCOUNT 6
66 #define OSPFAREALSACOUNT 7
67 #define OSPFAREALSACKSUMSUM 8
68 #define OSPFAREASUMMARY 9
69 #define OSPFAREASTATUS 10
71 /* OSPF MIB ospfStubAreaTable. */
72 #define OSPFSTUBAREAID 1
74 #define OSPFSTUBMETRIC 3
75 #define OSPFSTUBSTATUS 4
76 #define OSPFSTUBMETRICTYPE 5
78 /* OSPF MIB ospfLsdbTable. */
79 #define OSPFLSDBAREAID 1
80 #define OSPFLSDBTYPE 2
81 #define OSPFLSDBLSID 3
82 #define OSPFLSDBROUTERID 4
83 #define OSPFLSDBSEQUENCE 5
85 #define OSPFLSDBCHECKSUM 7
86 #define OSPFLSDBADVERTISEMENT 8
88 /* OSPF MIB ospfAreaRangeTable. */
89 #define OSPFAREARANGEAREAID 1
90 #define OSPFAREARANGENET 2
91 #define OSPFAREARANGEMASK 3
92 #define OSPFAREARANGESTATUS 4
93 #define OSPFAREARANGEEFFECT 5
95 /* OSPF MIB ospfHostTable. */
96 #define OSPFHOSTIPADDRESS 1
98 #define OSPFHOSTMETRIC 3
99 #define OSPFHOSTSTATUS 4
100 #define OSPFHOSTAREAID 5
102 /* OSPF MIB ospfIfTable. */
103 #define OSPFIFIPADDRESS 1
104 #define OSPFADDRESSLESSIF 2
105 #define OSPFIFAREAID 3
107 #define OSPFIFADMINSTAT 5
108 #define OSPFIFRTRPRIORITY 6
109 #define OSPFIFTRANSITDELAY 7
110 #define OSPFIFRETRANSINTERVAL 8
111 #define OSPFIFHELLOINTERVAL 9
112 #define OSPFIFRTRDEADINTERVAL 10
113 #define OSPFIFPOLLINTERVAL 11
114 #define OSPFIFSTATE 12
115 #define OSPFIFDESIGNATEDROUTER 13
116 #define OSPFIFBACKUPDESIGNATEDROUTER 14
117 #define OSPFIFEVENTS 15
118 #define OSPFIFAUTHKEY 16
119 #define OSPFIFSTATUS 17
120 #define OSPFIFMULTICASTFORWARDING 18
121 #define OSPFIFDEMAND 19
122 #define OSPFIFAUTHTYPE 20
124 /* OSPF MIB ospfIfMetricTable. */
125 #define OSPFIFMETRICIPADDRESS 1
126 #define OSPFIFMETRICADDRESSLESSIF 2
127 #define OSPFIFMETRICTOS 3
128 #define OSPFIFMETRICVALUE 4
129 #define OSPFIFMETRICSTATUS 5
131 /* OSPF MIB ospfVirtIfTable. */
132 #define OSPFVIRTIFAREAID 1
133 #define OSPFVIRTIFNEIGHBOR 2
134 #define OSPFVIRTIFTRANSITDELAY 3
135 #define OSPFVIRTIFRETRANSINTERVAL 4
136 #define OSPFVIRTIFHELLOINTERVAL 5
137 #define OSPFVIRTIFRTRDEADINTERVAL 6
138 #define OSPFVIRTIFSTATE 7
139 #define OSPFVIRTIFEVENTS 8
140 #define OSPFVIRTIFAUTHKEY 9
141 #define OSPFVIRTIFSTATUS 10
142 #define OSPFVIRTIFAUTHTYPE 11
144 /* OSPF MIB ospfNbrTable. */
145 #define OSPFNBRIPADDR 1
146 #define OSPFNBRADDRESSLESSINDEX 2
147 #define OSPFNBRRTRID 3
148 #define OSPFNBROPTIONS 4
149 #define OSPFNBRPRIORITY 5
150 #define OSPFNBRSTATE 6
151 #define OSPFNBREVENTS 7
152 #define OSPFNBRLSRETRANSQLEN 8
153 #define OSPFNBMANBRSTATUS 9
154 #define OSPFNBMANBRPERMANENCE 10
155 #define OSPFNBRHELLOSUPPRESSED 11
157 /* OSPF MIB ospfVirtNbrTable. */
158 #define OSPFVIRTNBRAREA 1
159 #define OSPFVIRTNBRRTRID 2
160 #define OSPFVIRTNBRIPADDR 3
161 #define OSPFVIRTNBROPTIONS 4
162 #define OSPFVIRTNBRSTATE 5
163 #define OSPFVIRTNBREVENTS 6
164 #define OSPFVIRTNBRLSRETRANSQLEN 7
165 #define OSPFVIRTNBRHELLOSUPPRESSED 8
167 /* OSPF MIB ospfExtLsdbTable. */
168 #define OSPFEXTLSDBTYPE 1
169 #define OSPFEXTLSDBLSID 2
170 #define OSPFEXTLSDBROUTERID 3
171 #define OSPFEXTLSDBSEQUENCE 4
172 #define OSPFEXTLSDBAGE 5
173 #define OSPFEXTLSDBCHECKSUM 6
174 #define OSPFEXTLSDBADVERTISEMENT 7
176 /* OSPF MIB ospfAreaAggregateTable. */
177 #define OSPFAREAAGGREGATEAREAID 1
178 #define OSPFAREAAGGREGATELSDBTYPE 2
179 #define OSPFAREAAGGREGATENET 3
180 #define OSPFAREAAGGREGATEMASK 4
181 #define OSPFAREAAGGREGATESTATUS 5
182 #define OSPFAREAAGGREGATEEFFECT 6
184 /* SYNTAX Status from OSPF-MIB. */
185 #define OSPF_STATUS_ENABLED 1
186 #define OSPF_STATUS_DISABLED 2
188 /* SNMP value hack. */
189 #define COUNTER ASN_COUNTER
190 #define INTEGER ASN_INTEGER
191 #define GAUGE ASN_GAUGE
192 #define TIMETICKS ASN_TIMETICKS
193 #define IPADDRESS ASN_IPADDRESS
194 #define STRING ASN_OCTET_STR
196 /* Because DR/DROther values are exhanged wrt RFC */
197 #define ISM_SNMP(x) \
198 (((x) == ISM_DROther) ? ISM_DR : ((x) == ISM_DR) ? ISM_DROther : (x))
200 /* Declare static local variables for convenience. */
203 /* OSPF-MIB instances. */
204 static oid ospf_oid
[] = {OSPF2MIB
};
205 static oid ospf_trap_oid
[] = {OSPF2MIB
, 16, 2}; /* Not reverse mappable! */
207 /* IP address 0.0.0.0. */
208 static struct in_addr ospf_empty_addr
= {.s_addr
= 0};
210 /* Hook functions. */
211 static uint8_t *ospfGeneralGroup(struct variable
*, oid
*, size_t *, int,
212 size_t *, WriteMethod
**);
213 static uint8_t *ospfAreaEntry(struct variable
*, oid
*, size_t *, int, size_t *,
215 static uint8_t *ospfStubAreaEntry(struct variable
*, oid
*, size_t *, int,
216 size_t *, WriteMethod
**);
217 static uint8_t *ospfLsdbEntry(struct variable
*, oid
*, size_t *, int, size_t *,
219 static uint8_t *ospfAreaRangeEntry(struct variable
*, oid
*, size_t *, int,
220 size_t *, WriteMethod
**);
221 static uint8_t *ospfHostEntry(struct variable
*, oid
*, size_t *, int, size_t *,
223 static uint8_t *ospfIfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
225 static uint8_t *ospfIfMetricEntry(struct variable
*, oid
*, size_t *, int,
226 size_t *, WriteMethod
**);
227 static uint8_t *ospfVirtIfEntry(struct variable
*, oid
*, size_t *, int,
228 size_t *, WriteMethod
**);
229 static uint8_t *ospfNbrEntry(struct variable
*, oid
*, size_t *, int, size_t *,
231 static uint8_t *ospfVirtNbrEntry(struct variable
*, oid
*, size_t *, int,
232 size_t *, WriteMethod
**);
233 static uint8_t *ospfExtLsdbEntry(struct variable
*, oid
*, size_t *, int,
234 size_t *, WriteMethod
**);
235 static uint8_t *ospfAreaAggregateEntry(struct variable
*, oid
*, size_t *, int,
236 size_t *, WriteMethod
**);
238 static struct variable ospf_variables
[] = {
239 /* OSPF general variables */
240 {OSPFROUTERID
, IPADDRESS
, RWRITE
, ospfGeneralGroup
, 2, {1, 1}},
241 {OSPFADMINSTAT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 2}},
242 {OSPFVERSIONNUMBER
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 3}},
243 {OSPFAREABDRRTRSTATUS
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 4}},
244 {OSPFASBDRRTRSTATUS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 5}},
245 {OSPFEXTERNLSACOUNT
, GAUGE
, RONLY
, ospfGeneralGroup
, 2, {1, 6}},
246 {OSPFEXTERNLSACKSUMSUM
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 7}},
247 {OSPFTOSSUPPORT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 8}},
248 {OSPFORIGINATENEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 9}},
249 {OSPFRXNEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 10}},
250 {OSPFEXTLSDBLIMIT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 11}},
251 {OSPFMULTICASTEXTENSIONS
,
257 {OSPFEXITOVERFLOWINTERVAL
,
263 {OSPFDEMANDEXTENSIONS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 14}},
265 /* OSPF area data structure. */
266 {OSPFAREAID
, IPADDRESS
, RONLY
, ospfAreaEntry
, 3, {2, 1, 1}},
267 {OSPFAUTHTYPE
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 2}},
268 {OSPFIMPORTASEXTERN
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 3}},
269 {OSPFSPFRUNS
, COUNTER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 4}},
270 {OSPFAREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 5}},
271 {OSPFASBDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 6}},
272 {OSPFAREALSACOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 7}},
273 {OSPFAREALSACKSUMSUM
, INTEGER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 8}},
274 {OSPFAREASUMMARY
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 9}},
275 {OSPFAREASTATUS
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 10}},
277 /* OSPF stub area information. */
278 {OSPFSTUBAREAID
, IPADDRESS
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 1}},
279 {OSPFSTUBTOS
, INTEGER
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 2}},
280 {OSPFSTUBMETRIC
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 3}},
281 {OSPFSTUBSTATUS
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 4}},
282 {OSPFSTUBMETRICTYPE
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 5}},
284 /* OSPF link state database. */
285 {OSPFLSDBAREAID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 1}},
286 {OSPFLSDBTYPE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 2}},
287 {OSPFLSDBLSID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 3}},
288 {OSPFLSDBROUTERID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 4}},
289 {OSPFLSDBSEQUENCE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 5}},
290 {OSPFLSDBAGE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 6}},
291 {OSPFLSDBCHECKSUM
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 7}},
292 {OSPFLSDBADVERTISEMENT
, STRING
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 8}},
294 /* Area range table. */
295 {OSPFAREARANGEAREAID
,
301 {OSPFAREARANGENET
, IPADDRESS
, RONLY
, ospfAreaRangeEntry
, 3, {5, 1, 2}},
308 {OSPFAREARANGESTATUS
,
314 {OSPFAREARANGEEFFECT
,
321 /* OSPF host table. */
322 {OSPFHOSTIPADDRESS
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 1}},
323 {OSPFHOSTTOS
, INTEGER
, RONLY
, ospfHostEntry
, 3, {6, 1, 2}},
324 {OSPFHOSTMETRIC
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 3}},
325 {OSPFHOSTSTATUS
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 4}},
326 {OSPFHOSTAREAID
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 5}},
328 /* OSPF interface table. */
329 {OSPFIFIPADDRESS
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 1}},
330 {OSPFADDRESSLESSIF
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 2}},
331 {OSPFIFAREAID
, IPADDRESS
, RWRITE
, ospfIfEntry
, 3, {7, 1, 3}},
332 {OSPFIFTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 4}},
333 {OSPFIFADMINSTAT
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 5}},
334 {OSPFIFRTRPRIORITY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 6}},
335 {OSPFIFTRANSITDELAY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 7}},
336 {OSPFIFRETRANSINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 8}},
337 {OSPFIFHELLOINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 9}},
338 {OSPFIFRTRDEADINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 10}},
339 {OSPFIFPOLLINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 11}},
340 {OSPFIFSTATE
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 12}},
341 {OSPFIFDESIGNATEDROUTER
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 13}},
342 {OSPFIFBACKUPDESIGNATEDROUTER
,
348 {OSPFIFEVENTS
, COUNTER
, RONLY
, ospfIfEntry
, 3, {7, 1, 15}},
349 {OSPFIFAUTHKEY
, STRING
, RWRITE
, ospfIfEntry
, 3, {7, 1, 16}},
350 {OSPFIFSTATUS
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 17}},
351 {OSPFIFMULTICASTFORWARDING
,
357 {OSPFIFDEMAND
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 19}},
358 {OSPFIFAUTHTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 20}},
360 /* OSPF interface metric table. */
361 {OSPFIFMETRICIPADDRESS
,
367 {OSPFIFMETRICADDRESSLESSIF
,
373 {OSPFIFMETRICTOS
, INTEGER
, RONLY
, ospfIfMetricEntry
, 3, {8, 1, 3}},
374 {OSPFIFMETRICVALUE
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 4}},
375 {OSPFIFMETRICSTATUS
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 5}},
377 /* OSPF virtual interface table. */
378 {OSPFVIRTIFAREAID
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 1}},
379 {OSPFVIRTIFNEIGHBOR
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 2}},
380 {OSPFVIRTIFTRANSITDELAY
,
386 {OSPFVIRTIFRETRANSINTERVAL
,
392 {OSPFVIRTIFHELLOINTERVAL
,
398 {OSPFVIRTIFRTRDEADINTERVAL
,
404 {OSPFVIRTIFSTATE
, INTEGER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 7}},
405 {OSPFVIRTIFEVENTS
, COUNTER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 8}},
406 {OSPFVIRTIFAUTHKEY
, STRING
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 9}},
407 {OSPFVIRTIFSTATUS
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 10}},
408 {OSPFVIRTIFAUTHTYPE
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 11}},
410 /* OSPF neighbor table. */
411 {OSPFNBRIPADDR
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 1}},
412 {OSPFNBRADDRESSLESSINDEX
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 2}},
413 {OSPFNBRRTRID
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 3}},
414 {OSPFNBROPTIONS
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 4}},
415 {OSPFNBRPRIORITY
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 5}},
416 {OSPFNBRSTATE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 6}},
417 {OSPFNBREVENTS
, COUNTER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 7}},
418 {OSPFNBRLSRETRANSQLEN
, GAUGE
, RONLY
, ospfNbrEntry
, 3, {10, 1, 8}},
419 {OSPFNBMANBRSTATUS
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 9}},
420 {OSPFNBMANBRPERMANENCE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 10}},
421 {OSPFNBRHELLOSUPPRESSED
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 11}},
423 /* OSPF virtual neighbor table. */
424 {OSPFVIRTNBRAREA
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 1}},
425 {OSPFVIRTNBRRTRID
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 2}},
426 {OSPFVIRTNBRIPADDR
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 3}},
427 {OSPFVIRTNBROPTIONS
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 4}},
428 {OSPFVIRTNBRSTATE
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 5}},
429 {OSPFVIRTNBREVENTS
, COUNTER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 6}},
430 {OSPFVIRTNBRLSRETRANSQLEN
,
436 {OSPFVIRTNBRHELLOSUPPRESSED
,
443 /* OSPF link state database, external. */
444 {OSPFEXTLSDBTYPE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 1}},
445 {OSPFEXTLSDBLSID
, IPADDRESS
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 2}},
446 {OSPFEXTLSDBROUTERID
,
452 {OSPFEXTLSDBSEQUENCE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 4}},
453 {OSPFEXTLSDBAGE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 5}},
454 {OSPFEXTLSDBCHECKSUM
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 6}},
455 {OSPFEXTLSDBADVERTISEMENT
,
462 /* OSPF area aggregate table. */
463 {OSPFAREAAGGREGATEAREAID
,
466 ospfAreaAggregateEntry
,
469 {OSPFAREAAGGREGATELSDBTYPE
,
472 ospfAreaAggregateEntry
,
475 {OSPFAREAAGGREGATENET
,
478 ospfAreaAggregateEntry
,
481 {OSPFAREAAGGREGATEMASK
,
484 ospfAreaAggregateEntry
,
487 {OSPFAREAAGGREGATESTATUS
,
490 ospfAreaAggregateEntry
,
493 {OSPFAREAAGGREGATEEFFECT
,
496 ospfAreaAggregateEntry
,
500 /* The administrative status of OSPF. When OSPF is enbled on at least
501 one interface return 1. */
502 static int ospf_admin_stat(struct ospf
*ospf
)
504 struct listnode
*node
;
505 struct ospf_interface
*oi
;
510 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
511 if (oi
&& oi
->address
)
517 static uint8_t *ospfGeneralGroup(struct variable
*v
, oid
*name
, size_t *length
,
518 int exact
, size_t *var_len
,
519 WriteMethod
**write_method
)
523 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
525 /* Check whether the instance identifier is valid */
526 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
530 /* Return the current value of the variable */
532 case OSPFROUTERID
: /* 1 */
533 /* Router-ID of this OSPF instance. */
535 return SNMP_IPADDRESS(ospf
->router_id
);
537 return SNMP_IPADDRESS(ospf_empty_addr
);
538 case OSPFADMINSTAT
: /* 2 */
539 /* The administrative status of OSPF in the router. */
540 if (ospf_admin_stat(ospf
))
541 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
543 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
544 case OSPFVERSIONNUMBER
: /* 3 */
545 /* OSPF version 2. */
546 return SNMP_INTEGER(OSPF_VERSION
);
547 case OSPFAREABDRRTRSTATUS
: /* 4 */
548 /* Area Border router status. */
549 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ABR
))
550 return SNMP_INTEGER(SNMP_TRUE
);
552 return SNMP_INTEGER(SNMP_FALSE
);
553 case OSPFASBDRRTRSTATUS
: /* 5 */
554 /* AS Border router status. */
555 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ASBR
))
556 return SNMP_INTEGER(SNMP_TRUE
);
558 return SNMP_INTEGER(SNMP_FALSE
);
559 case OSPFEXTERNLSACOUNT
: /* 6 */
560 /* External LSA counts. */
562 return SNMP_INTEGER(ospf_lsdb_count_all(ospf
->lsdb
));
564 return SNMP_INTEGER(0);
565 case OSPFEXTERNLSACKSUMSUM
: /* 7 */
566 /* External LSA checksum. */
567 return SNMP_INTEGER(0);
568 case OSPFTOSSUPPORT
: /* 8 */
569 /* TOS is not supported. */
570 return SNMP_INTEGER(SNMP_FALSE
);
571 case OSPFORIGINATENEWLSAS
: /* 9 */
572 /* The number of new link-state advertisements. */
574 return SNMP_INTEGER(ospf
->lsa_originate_count
);
576 return SNMP_INTEGER(0);
577 case OSPFRXNEWLSAS
: /* 10 */
578 /* The number of link-state advertisements received determined
579 to be new instantiations. */
581 return SNMP_INTEGER(ospf
->rx_lsa_count
);
583 return SNMP_INTEGER(0);
584 case OSPFEXTLSDBLIMIT
: /* 11 */
585 /* There is no limit for the number of non-default
587 return SNMP_INTEGER(-1);
588 case OSPFMULTICASTEXTENSIONS
: /* 12 */
589 /* Multicast Extensions to OSPF is not supported. */
590 return SNMP_INTEGER(0);
591 case OSPFEXITOVERFLOWINTERVAL
: /* 13 */
592 /* Overflow is not supported. */
593 return SNMP_INTEGER(0);
594 case OSPFDEMANDEXTENSIONS
: /* 14 */
595 /* Demand routing is not supported. */
596 return SNMP_INTEGER(SNMP_FALSE
);
603 static struct ospf_area
*
604 ospf_area_lookup_next(struct ospf
*ospf
, struct in_addr
*area_id
, int first
)
606 struct ospf_area
*area
;
607 struct listnode
*node
;
613 node
= listhead(ospf
->areas
);
615 area
= listgetdata(node
);
616 *area_id
= area
->area_id
;
621 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
622 if (ntohl(area
->area_id
.s_addr
) > ntohl(area_id
->s_addr
)) {
623 *area_id
= area
->area_id
;
630 static struct ospf_area
*ospfAreaLookup(struct variable
*v
, oid name
[],
631 size_t *length
, struct in_addr
*addr
,
635 struct ospf_area
*area
;
638 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
643 /* Length is insufficient to lookup OSPF area. */
644 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
647 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
649 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
653 len
= *length
- v
->namelen
;
657 oid2in_addr(name
+ v
->namelen
, len
, addr
);
659 area
= ospf_area_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
664 oid_copy_in_addr(name
+ v
->namelen
, addr
);
665 *length
= sizeof(struct in_addr
) + v
->namelen
;
672 static uint8_t *ospfAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
673 int exact
, size_t *var_len
,
674 WriteMethod
**write_method
)
676 struct ospf_area
*area
;
679 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
683 memset(&addr
, 0, sizeof(addr
));
685 area
= ospfAreaLookup(v
, name
, length
, &addr
, exact
);
689 /* Return the current value of the variable */
691 case OSPFAREAID
: /* 1 */
692 return SNMP_IPADDRESS(area
->area_id
);
693 case OSPFAUTHTYPE
: /* 2 */
694 return SNMP_INTEGER(area
->auth_type
);
695 case OSPFIMPORTASEXTERN
: /* 3 */
696 return SNMP_INTEGER(area
->external_routing
+ 1);
697 case OSPFSPFRUNS
: /* 4 */
698 return SNMP_INTEGER(area
->spf_calculation
);
699 case OSPFAREABDRRTRCOUNT
: /* 5 */
700 return SNMP_INTEGER(area
->abr_count
);
701 case OSPFASBDRRTRCOUNT
: /* 6 */
702 return SNMP_INTEGER(area
->asbr_count
);
703 case OSPFAREALSACOUNT
: /* 7 */
704 return SNMP_INTEGER(area
->lsdb
->total
);
705 case OSPFAREALSACKSUMSUM
: /* 8 */
706 return SNMP_INTEGER(0);
707 case OSPFAREASUMMARY
: /* 9 */
708 #define OSPF_noAreaSummary 1
709 #define OSPF_sendAreaSummary 2
710 if (area
->no_summary
)
711 return SNMP_INTEGER(OSPF_noAreaSummary
);
713 return SNMP_INTEGER(OSPF_sendAreaSummary
);
714 case OSPFAREASTATUS
: /* 10 */
715 return SNMP_INTEGER(SNMP_VALID
);
722 static struct ospf_area
*ospf_stub_area_lookup_next(struct in_addr
*area_id
,
725 struct ospf_area
*area
;
726 struct listnode
*node
;
729 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
733 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
734 if (area
->external_routing
== OSPF_AREA_STUB
) {
736 *area_id
= area
->area_id
;
738 } else if (ntohl(area
->area_id
.s_addr
)
739 > ntohl(area_id
->s_addr
)) {
740 *area_id
= area
->area_id
;
748 static struct ospf_area
*ospfStubAreaLookup(struct variable
*v
, oid name
[],
750 struct in_addr
*addr
, int exact
)
753 struct ospf_area
*area
;
756 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
762 /* ospfStubAreaID + ospfStubTOS. */
763 if (*length
!= v
->namelen
+ sizeof(struct in_addr
) + 1)
766 /* Check ospfStubTOS is zero. */
767 if (name
[*length
- 1] != 0)
770 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
772 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
774 if (area
&& area
->external_routing
== OSPF_AREA_STUB
)
779 len
= *length
- v
->namelen
;
783 oid2in_addr(name
+ v
->namelen
, len
, addr
);
785 area
= ospf_stub_area_lookup_next(addr
, len
== 0 ? 1 : 0);
790 oid_copy_in_addr(name
+ v
->namelen
, addr
);
792 name
[v
->namelen
+ sizeof(struct in_addr
)] = 0;
793 *length
= v
->namelen
+ sizeof(struct in_addr
) + 1;
800 static uint8_t *ospfStubAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
801 int exact
, size_t *var_len
,
802 WriteMethod
**write_method
)
804 struct ospf_area
*area
;
807 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
811 memset(&addr
, 0, sizeof(addr
));
813 area
= ospfStubAreaLookup(v
, name
, length
, &addr
, exact
);
817 /* Return the current value of the variable */
819 case OSPFSTUBAREAID
: /* 1 */
820 /* OSPF stub area id. */
821 return SNMP_IPADDRESS(area
->area_id
);
822 case OSPFSTUBTOS
: /* 2 */
823 /* TOS value is not supported. */
824 return SNMP_INTEGER(0);
825 case OSPFSTUBMETRIC
: /* 3 */
826 /* Default cost to stub area. */
827 return SNMP_INTEGER(area
->default_cost
);
828 case OSPFSTUBSTATUS
: /* 4 */
829 /* Status of the stub area. */
830 return SNMP_INTEGER(SNMP_VALID
);
831 case OSPFSTUBMETRICTYPE
: /* 5 */
832 /* OSPF Metric type. */
833 #define OSPF_ospfMetric 1
834 #define OSPF_comparableCost 2
835 #define OSPF_nonComparable 3
836 return SNMP_INTEGER(OSPF_ospfMetric
);
843 static struct ospf_lsa
*lsdb_lookup_next(struct ospf_area
*area
, uint8_t *type
,
844 int type_next
, struct in_addr
*ls_id
,
846 struct in_addr
*router_id
,
849 struct ospf_lsa
*lsa
;
857 /* Sanity check, if LSA type unknwon
858 merley skip any LSA */
859 if ((i
< OSPF_MIN_LSA
) || (i
>= OSPF_MAX_LSA
)) {
860 zlog_debug("Strange request with LSA type %d", i
);
864 for (; i
< OSPF_MAX_LSA
; i
++) {
867 lsa
= ospf_lsdb_lookup_by_id_next(area
->lsdb
, *type
, *ls_id
,
868 *router_id
, ls_id_next
);
877 static struct ospf_lsa
*ospfLsdbLookup(struct variable
*v
, oid
*name
,
878 size_t *length
, struct in_addr
*area_id
,
879 uint8_t *type
, struct in_addr
*ls_id
,
880 struct in_addr
*router_id
, int exact
)
883 struct ospf_area
*area
;
884 struct ospf_lsa
*lsa
;
892 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
894 #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
897 /* Area ID + Type + LS ID + Router ID. */
898 if (*length
- v
->namelen
!= OSPF_LSDB_ENTRY_OFFSET
)
901 /* Set OID offset for Area ID. */
902 offset
= name
+ v
->namelen
;
904 /* Lookup area first. */
905 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
906 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
909 offset
+= IN_ADDR_SIZE
;
916 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
917 offset
+= IN_ADDR_SIZE
;
920 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
923 return ospf_lsdb_lookup_by_id(area
->lsdb
, *type
, *ls_id
,
926 /* Get variable length. */
927 offset
= name
+ v
->namelen
;
928 offsetlen
= *length
- v
->namelen
;
931 if (len
> (int)IN_ADDR_SIZE
)
934 oid2in_addr(offset
, len
, area_id
);
936 /* First we search area. */
937 if (len
== IN_ADDR_SIZE
)
938 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
940 area
= ospf_area_lookup_next(ospf
, area_id
, 1);
946 /* Next we lookup type. */
967 if (len
> (int)IN_ADDR_SIZE
)
970 oid2in_addr(offset
, len
, ls_id
);
974 offset
+= IN_ADDR_SIZE
;
975 offsetlen
-= IN_ADDR_SIZE
;
982 if (len
> (int)IN_ADDR_SIZE
)
985 oid2in_addr(offset
, len
, router_id
);
988 lsa
= lsdb_lookup_next(area
, type
, type_next
, ls_id
,
989 ls_id_next
, router_id
,
993 /* Fill in length. */
994 *length
= v
->namelen
+ OSPF_LSDB_ENTRY_OFFSET
;
997 offset
= name
+ v
->namelen
;
998 oid_copy_in_addr(offset
, area_id
);
999 offset
+= IN_ADDR_SIZE
;
1000 *offset
= lsa
->data
->type
;
1002 oid_copy_in_addr(offset
, &lsa
->data
->id
);
1003 offset
+= IN_ADDR_SIZE
;
1004 oid_copy_in_addr(offset
,
1005 &lsa
->data
->adv_router
);
1009 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1015 static uint8_t *ospfLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
1016 int exact
, size_t *var_len
,
1017 WriteMethod
**write_method
)
1019 struct ospf_lsa
*lsa
;
1020 struct lsa_header
*lsah
;
1021 struct in_addr area_id
;
1023 struct in_addr ls_id
;
1024 struct in_addr router_id
;
1027 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1031 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1032 ospfLsdbLsid, ospfLsdbRouterId } */
1034 memset(&area_id
, 0, sizeof(area_id
));
1036 memset(&ls_id
, 0, sizeof(ls_id
));
1037 memset(&router_id
, 0, sizeof(router_id
));
1039 /* Check OSPF instance. */
1040 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1044 lsa
= ospfLsdbLookup(v
, name
, length
, &area_id
, &type
, &ls_id
,
1051 /* Return the current value of the variable */
1053 case OSPFLSDBAREAID
: /* 1 */
1054 return SNMP_IPADDRESS(lsa
->area
->area_id
);
1055 case OSPFLSDBTYPE
: /* 2 */
1056 return SNMP_INTEGER(lsah
->type
);
1057 case OSPFLSDBLSID
: /* 3 */
1058 return SNMP_IPADDRESS(lsah
->id
);
1059 case OSPFLSDBROUTERID
: /* 4 */
1060 return SNMP_IPADDRESS(lsah
->adv_router
);
1061 case OSPFLSDBSEQUENCE
: /* 5 */
1062 return SNMP_INTEGER(lsah
->ls_seqnum
);
1063 case OSPFLSDBAGE
: /* 6 */
1064 return SNMP_INTEGER(lsah
->ls_age
);
1065 case OSPFLSDBCHECKSUM
: /* 7 */
1066 return SNMP_INTEGER(lsah
->checksum
);
1067 case OSPFLSDBADVERTISEMENT
: /* 8 */
1068 *var_len
= ntohs(lsah
->length
);
1069 return (uint8_t *)lsah
;
1076 static struct ospf_area_range
*ospfAreaRangeLookup(struct variable
*v
,
1077 oid
*name
, size_t *length
,
1078 struct in_addr
*area_id
,
1079 struct in_addr
*range_net
,
1086 struct ospf_area
*area
;
1087 struct ospf_area_range
*range
;
1088 struct prefix_ipv4 p
;
1090 p
.prefixlen
= IPV4_MAX_BITLEN
;
1092 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1095 /* Area ID + Range Network. */
1096 if (v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
!= *length
)
1099 /* Set OID offset for Area ID. */
1100 offset
= name
+ v
->namelen
;
1102 /* Lookup area first. */
1103 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
1105 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1109 offset
+= IN_ADDR_SIZE
;
1111 /* Lookup area range. */
1112 oid2in_addr(offset
, IN_ADDR_SIZE
, range_net
);
1113 p
.prefix
= *range_net
;
1115 return ospf_area_range_lookup(area
, area
->ranges
, &p
);
1117 /* Set OID offset for Area ID. */
1118 offset
= name
+ v
->namelen
;
1119 offsetlen
= *length
- v
->namelen
;
1122 if (len
> (int)IN_ADDR_SIZE
)
1125 oid2in_addr(offset
, len
, area_id
);
1127 /* First we search area. */
1128 if (len
== IN_ADDR_SIZE
)
1129 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1131 area
= ospf_area_lookup_next(ospf
, area_id
,
1138 offset
+= IN_ADDR_SIZE
;
1139 offsetlen
-= IN_ADDR_SIZE
;
1144 if (len
> (int)IN_ADDR_SIZE
)
1147 oid2in_addr(offset
, len
, range_net
);
1149 range
= ospf_area_range_lookup_next(area
, range_net
,
1153 /* Fill in length. */
1154 *length
= v
->namelen
+ IN_ADDR_SIZE
1157 /* Fill in value. */
1158 offset
= name
+ v
->namelen
;
1159 oid_copy_in_addr(offset
, area_id
);
1160 offset
+= IN_ADDR_SIZE
;
1161 oid_copy_in_addr(offset
, range_net
);
1165 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1171 static uint8_t *ospfAreaRangeEntry(struct variable
*v
, oid
*name
,
1172 size_t *length
, int exact
, size_t *var_len
,
1173 WriteMethod
**write_method
)
1175 struct ospf_area_range
*range
;
1176 struct in_addr area_id
;
1177 struct in_addr range_net
;
1178 struct in_addr mask
;
1181 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1185 /* Check OSPF instance. */
1186 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1190 memset(&area_id
, 0, IN_ADDR_SIZE
);
1191 memset(&range_net
, 0, IN_ADDR_SIZE
);
1193 range
= ospfAreaRangeLookup(v
, name
, length
, &area_id
, &range_net
,
1198 /* Convert prefixlen to network mask format. */
1199 masklen2ip(range
->subst_masklen
, &mask
);
1201 /* Return the current value of the variable */
1203 case OSPFAREARANGEAREAID
: /* 1 */
1204 return SNMP_IPADDRESS(area_id
);
1205 case OSPFAREARANGENET
: /* 2 */
1206 return SNMP_IPADDRESS(range_net
);
1207 case OSPFAREARANGEMASK
: /* 3 */
1208 return SNMP_IPADDRESS(mask
);
1209 case OSPFAREARANGESTATUS
: /* 4 */
1210 return SNMP_INTEGER(SNMP_VALID
);
1211 case OSPFAREARANGEEFFECT
: /* 5 */
1212 #define OSPF_advertiseMatching 1
1213 #define OSPF_doNotAdvertiseMatching 2
1214 return SNMP_INTEGER(OSPF_advertiseMatching
);
1221 static struct ospf_nbr_nbma
*ospfHostLookup(struct variable
*v
, oid
*name
,
1223 struct in_addr
*addr
, int exact
)
1225 struct ospf_nbr_nbma
*nbr_nbma
;
1228 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1233 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1234 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1237 /* Check ospfHostTOS. */
1238 if (name
[*length
- 1] != 0)
1241 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, addr
);
1243 nbr_nbma
= ospf_nbr_nbma_lookup(ospf
, *addr
);
1251 static uint8_t *ospfHostEntry(struct variable
*v
, oid
*name
, size_t *length
,
1252 int exact
, size_t *var_len
,
1253 WriteMethod
**write_method
)
1255 struct ospf_nbr_nbma
*nbr_nbma
;
1256 struct ospf_interface
*oi
;
1257 struct in_addr addr
;
1260 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1264 /* Check OSPF instance. */
1265 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1269 memset(&addr
, 0, sizeof(addr
));
1271 nbr_nbma
= ospfHostLookup(v
, name
, length
, &addr
, exact
);
1272 if (nbr_nbma
== NULL
)
1277 /* Return the current value of the variable */
1279 case OSPFHOSTIPADDRESS
: /* 1 */
1280 return SNMP_IPADDRESS(nbr_nbma
->addr
);
1281 case OSPFHOSTTOS
: /* 2 */
1282 return SNMP_INTEGER(0);
1283 case OSPFHOSTMETRIC
: /* 3 */
1285 return SNMP_INTEGER(oi
->output_cost
);
1287 return SNMP_INTEGER(1);
1288 case OSPFHOSTSTATUS
: /* 4 */
1289 return SNMP_INTEGER(SNMP_VALID
);
1290 case OSPFHOSTAREAID
: /* 5 */
1292 return SNMP_IPADDRESS(oi
->area
->area_id
);
1294 return SNMP_IPADDRESS(ospf_empty_addr
);
1301 static struct list
*ospf_snmp_iflist
;
1303 struct ospf_snmp_if
{
1304 struct in_addr addr
;
1306 struct interface
*ifp
;
1309 static struct ospf_snmp_if
*ospf_snmp_if_new(void)
1311 return XCALLOC(MTYPE_SNMP
, sizeof(struct ospf_snmp_if
));
1314 static void ospf_snmp_if_free(struct ospf_snmp_if
*osif
)
1316 XFREE(MTYPE_SNMP
, osif
);
1319 static int ospf_snmp_if_delete(struct interface
*ifp
)
1321 struct listnode
*node
, *nnode
;
1322 struct ospf_snmp_if
*osif
;
1324 for (ALL_LIST_ELEMENTS(ospf_snmp_iflist
, node
, nnode
, osif
)) {
1325 if (osif
->ifp
== ifp
) {
1326 list_delete_node(ospf_snmp_iflist
, node
);
1327 ospf_snmp_if_free(osif
);
1334 static int ospf_snmp_if_update(struct interface
*ifp
)
1336 struct listnode
*node
;
1337 struct listnode
*pn
;
1338 struct connected
*ifc
;
1340 struct ospf_snmp_if
*osif
;
1341 struct in_addr
*addr
;
1344 ospf_snmp_if_delete(ifp
);
1350 /* Lookup first IPv4 address entry. */
1351 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1352 p
= CONNECTED_ID(ifc
);
1354 if (p
->family
== AF_INET
) {
1355 addr
= &p
->u
.prefix4
;
1360 ifindex
= ifp
->ifindex
;
1362 /* Add interface to the list. */
1364 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1366 /* Usual interfaces --> Sort them based on interface
1368 if (ntohl(osif
->addr
.s_addr
) > ntohl(addr
->s_addr
))
1371 /* Unnumbered interfaces --> Sort them based on
1372 * interface indexes */
1373 if (osif
->addr
.s_addr
!= INADDR_ANY
1374 || osif
->ifindex
> ifindex
)
1380 osif
= ospf_snmp_if_new();
1381 if (addr
) /* Usual interface */
1385 /* This field is used for storing ospfAddressLessIf OID value,
1386 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1387 * usual interface */
1389 } else /* Unnumbered interface */
1390 osif
->ifindex
= ifindex
;
1393 listnode_add_after(ospf_snmp_iflist
, pn
, osif
);
1397 static int ospf_snmp_is_if_have_addr(struct interface
*ifp
)
1399 struct listnode
*nn
;
1400 struct connected
*ifc
;
1402 /* Is this interface having any connected IPv4 address ? */
1403 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, nn
, ifc
)) {
1404 if (CONNECTED_PREFIX(ifc
)->family
== AF_INET
)
1411 static struct ospf_interface
*ospf_snmp_if_lookup(struct in_addr
*ifaddr
,
1414 struct listnode
*node
;
1415 struct ospf_snmp_if
*osif
;
1416 struct ospf_interface
*oi
= NULL
;
1417 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1419 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1420 if (ifaddr
->s_addr
) {
1421 if (IPV4_ADDR_SAME(&osif
->addr
, ifaddr
))
1422 oi
= ospf_if_lookup_by_local_addr(
1423 ospf
, osif
->ifp
, *ifaddr
);
1425 if (osif
->ifindex
== *ifindex
)
1426 oi
= ospf_if_lookup_by_local_addr(
1427 ospf
, osif
->ifp
, *ifaddr
);
1433 static struct ospf_interface
*ospf_snmp_if_lookup_next(struct in_addr
*ifaddr
,
1436 ifindex_t ifindex_next
)
1438 struct ospf_snmp_if
*osif
;
1439 struct listnode
*nn
;
1440 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1441 struct ospf_interface
*oi
= NULL
;
1446 /* No instance is specified --> Return the first OSPF interface */
1448 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1449 osif
= listgetdata(nn
);
1450 *ifaddr
= osif
->addr
;
1451 *ifindex
= osif
->ifindex
;
1452 /* Because no instance is specified, we don't care about
1454 * interface (usual or unnumbered), just returning the
1457 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1465 /* An instance is specified --> Return the next OSPF interface */
1466 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1467 /* Usual interface */
1468 if (ifaddr
->s_addr
) {
1469 /* The interface must have valid AF_INET connected
1471 /* it must have lager IPv4 address value than the lookup
1473 if ((ospf_snmp_is_if_have_addr(osif
->ifp
))
1474 && (ntohl(osif
->addr
.s_addr
)
1475 > ntohl(ifaddr
->s_addr
))) {
1476 *ifaddr
= osif
->addr
;
1477 *ifindex
= osif
->ifindex
;
1479 /* and it must be an OSPF interface */
1480 oi
= ospf_if_lookup_by_local_addr(
1481 ospf
, osif
->ifp
, *ifaddr
);
1486 /* Unnumbered interface */
1488 /* The interface must NOT have valid AF_INET connected
1490 /* it must have lager interface index than the lookup
1492 if ((!ospf_snmp_is_if_have_addr(osif
->ifp
))
1493 && (osif
->ifindex
> *ifindex
)) {
1494 *ifaddr
= osif
->addr
;
1495 *ifindex
= osif
->ifindex
;
1497 /* and it must be an OSPF interface */
1498 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1507 static int ospf_snmp_iftype(struct interface
*ifp
)
1509 #define ospf_snmp_iftype_broadcast 1
1510 #define ospf_snmp_iftype_nbma 2
1511 #define ospf_snmp_iftype_pointToPoint 3
1512 #define ospf_snmp_iftype_pointToMultipoint 5
1513 if (if_is_broadcast(ifp
))
1514 return ospf_snmp_iftype_broadcast
;
1515 if (if_is_pointopoint(ifp
))
1516 return ospf_snmp_iftype_pointToPoint
;
1517 return ospf_snmp_iftype_broadcast
;
1520 static struct ospf_interface
*ospfIfLookup(struct variable
*v
, oid
*name
,
1522 struct in_addr
*ifaddr
,
1523 ifindex_t
*ifindex
, int exact
)
1526 int ifaddr_next
= 0;
1527 ifindex_t ifindex_next
= 0;
1528 struct ospf_interface
*oi
;
1532 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1535 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1536 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1538 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1540 len
= *length
- v
->namelen
;
1541 if (len
>= IN_ADDR_SIZE
)
1546 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1548 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1555 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1557 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1560 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1561 offset
= name
+ v
->namelen
;
1562 oid_copy_in_addr(offset
, ifaddr
);
1563 offset
+= IN_ADDR_SIZE
;
1571 static uint8_t *ospfIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1572 int exact
, size_t *var_len
,
1573 WriteMethod
**write_method
)
1576 struct in_addr ifaddr
;
1577 struct ospf_interface
*oi
;
1580 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1585 memset(&ifaddr
, 0, sizeof(ifaddr
));
1587 /* Check OSPF instance. */
1588 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1592 oi
= ospfIfLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1596 /* Return the current value of the variable */
1598 case OSPFIFIPADDRESS
: /* 1 */
1599 return SNMP_IPADDRESS(ifaddr
);
1600 case OSPFADDRESSLESSIF
: /* 2 */
1601 return SNMP_INTEGER(ifindex
);
1602 case OSPFIFAREAID
: /* 3 */
1604 return SNMP_IPADDRESS(oi
->area
->area_id
);
1606 return SNMP_IPADDRESS(ospf_empty_addr
);
1607 case OSPFIFTYPE
: /* 4 */
1608 return SNMP_INTEGER(ospf_snmp_iftype(oi
->ifp
));
1609 case OSPFIFADMINSTAT
: /* 5 */
1611 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1613 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1614 case OSPFIFRTRPRIORITY
: /* 6 */
1615 return SNMP_INTEGER(PRIORITY(oi
));
1616 case OSPFIFTRANSITDELAY
: /* 7 */
1617 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1618 case OSPFIFRETRANSINTERVAL
: /* 8 */
1619 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1620 case OSPFIFHELLOINTERVAL
: /* 9 */
1621 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1622 case OSPFIFRTRDEADINTERVAL
: /* 10 */
1623 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1624 case OSPFIFPOLLINTERVAL
: /* 11 */
1625 return SNMP_INTEGER(OSPF_POLL_INTERVAL_DEFAULT
);
1626 case OSPFIFSTATE
: /* 12 */
1627 return SNMP_INTEGER(ISM_SNMP(oi
->state
));
1628 case OSPFIFDESIGNATEDROUTER
: /* 13 */
1629 return SNMP_IPADDRESS(DR(oi
));
1630 case OSPFIFBACKUPDESIGNATEDROUTER
: /* 14 */
1631 return SNMP_IPADDRESS(BDR(oi
));
1632 case OSPFIFEVENTS
: /* 15 */
1633 return SNMP_INTEGER(oi
->state_change
);
1634 case OSPFIFAUTHKEY
: /* 16 */
1636 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1637 case OSPFIFSTATUS
: /* 17 */
1638 return SNMP_INTEGER(SNMP_VALID
);
1639 case OSPFIFMULTICASTFORWARDING
: /* 18 */
1640 #define ospf_snmp_multiforward_blocked 1
1641 #define ospf_snmp_multiforward_multicast 2
1642 #define ospf_snmp_multiforward_unicast 3
1643 return SNMP_INTEGER(ospf_snmp_multiforward_blocked
);
1644 case OSPFIFDEMAND
: /* 19 */
1645 return SNMP_INTEGER(SNMP_FALSE
);
1646 case OSPFIFAUTHTYPE
: /* 20 */
1648 return SNMP_INTEGER(oi
->area
->auth_type
);
1650 return SNMP_INTEGER(0);
1657 #define OSPF_SNMP_METRIC_VALUE 1
1659 static struct ospf_interface
*ospfIfMetricLookup(struct variable
*v
, oid
*name
,
1661 struct in_addr
*ifaddr
,
1662 ifindex_t
*ifindex
, int exact
)
1665 int ifaddr_next
= 0;
1666 ifindex_t ifindex_next
= 0;
1667 struct ospf_interface
*oi
;
1672 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1)
1675 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1676 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1677 metric
= name
[v
->namelen
+ IN_ADDR_SIZE
+ 1];
1679 if (metric
!= OSPF_SNMP_METRIC_VALUE
)
1682 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1684 len
= *length
- v
->namelen
;
1685 if (len
>= IN_ADDR_SIZE
)
1690 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1692 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1699 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1701 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1704 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1;
1705 offset
= name
+ v
->namelen
;
1706 oid_copy_in_addr(offset
, ifaddr
);
1707 offset
+= IN_ADDR_SIZE
;
1710 *offset
= OSPF_SNMP_METRIC_VALUE
;
1717 static uint8_t *ospfIfMetricEntry(struct variable
*v
, oid
*name
, size_t *length
,
1718 int exact
, size_t *var_len
,
1719 WriteMethod
**write_method
)
1721 /* Currently we support metric 1 only. */
1723 struct in_addr ifaddr
;
1724 struct ospf_interface
*oi
;
1727 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1732 memset(&ifaddr
, 0, sizeof(ifaddr
));
1734 /* Check OSPF instance. */
1735 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1739 oi
= ospfIfMetricLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1743 /* Return the current value of the variable */
1745 case OSPFIFMETRICIPADDRESS
:
1746 return SNMP_IPADDRESS(ifaddr
);
1747 case OSPFIFMETRICADDRESSLESSIF
:
1748 return SNMP_INTEGER(ifindex
);
1749 case OSPFIFMETRICTOS
:
1750 return SNMP_INTEGER(0);
1751 case OSPFIFMETRICVALUE
:
1752 return SNMP_INTEGER(OSPF_SNMP_METRIC_VALUE
);
1753 case OSPFIFMETRICSTATUS
:
1754 return SNMP_INTEGER(1);
1761 static struct route_table
*ospf_snmp_vl_table
;
1763 static int ospf_snmp_vl_add(struct ospf_vl_data
*vl_data
)
1765 struct prefix_ls lp
;
1766 struct route_node
*rn
;
1768 memset(&lp
, 0, sizeof(lp
));
1769 lp
.family
= AF_UNSPEC
;
1771 lp
.id
= vl_data
->vl_area_id
;
1772 lp
.adv_router
= vl_data
->vl_peer
;
1774 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1776 route_unlock_node(rn
);
1782 static int ospf_snmp_vl_delete(struct ospf_vl_data
*vl_data
)
1784 struct prefix_ls lp
;
1785 struct route_node
*rn
;
1787 memset(&lp
, 0, sizeof(lp
));
1788 lp
.family
= AF_UNSPEC
;
1790 lp
.id
= vl_data
->vl_area_id
;
1791 lp
.adv_router
= vl_data
->vl_peer
;
1793 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1797 route_unlock_node(rn
);
1798 route_unlock_node(rn
);
1802 static struct ospf_vl_data
*ospf_snmp_vl_lookup(struct in_addr
*area_id
,
1803 struct in_addr
*neighbor
)
1805 struct prefix_ls lp
;
1806 struct route_node
*rn
;
1807 struct ospf_vl_data
*vl_data
;
1809 memset(&lp
, 0, sizeof(lp
));
1810 lp
.family
= AF_UNSPEC
;
1813 lp
.adv_router
= *neighbor
;
1815 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1818 route_unlock_node(rn
);
1824 static struct ospf_vl_data
*ospf_snmp_vl_lookup_next(struct in_addr
*area_id
,
1825 struct in_addr
*neighbor
,
1828 struct prefix_ls lp
;
1829 struct route_node
*rn
;
1830 struct ospf_vl_data
*vl_data
;
1832 memset(&lp
, 0, sizeof(lp
));
1833 lp
.family
= AF_UNSPEC
;
1836 lp
.adv_router
= *neighbor
;
1839 rn
= route_top(ospf_snmp_vl_table
);
1841 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1842 rn
= route_next(rn
);
1845 for (; rn
; rn
= route_next(rn
))
1849 if (rn
&& rn
->info
) {
1851 *area_id
= vl_data
->vl_area_id
;
1852 *neighbor
= vl_data
->vl_peer
;
1853 route_unlock_node(rn
);
1859 static struct ospf_vl_data
*
1860 ospfVirtIfLookup(struct variable
*v
, oid
*name
, size_t *length
,
1861 struct in_addr
*area_id
, struct in_addr
*neighbor
, int exact
)
1865 struct ospf_vl_data
*vl_data
;
1868 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
1871 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, area_id
);
1872 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, IN_ADDR_SIZE
,
1875 return ospf_snmp_vl_lookup(area_id
, neighbor
);
1879 len
= *length
- v
->namelen
;
1882 if (len
> IN_ADDR_SIZE
)
1884 oid2in_addr(name
+ v
->namelen
, len
, area_id
);
1886 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1887 if (len
> IN_ADDR_SIZE
)
1889 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, len
, neighbor
);
1891 vl_data
= ospf_snmp_vl_lookup_next(area_id
, neighbor
, first
);
1894 *length
= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
1895 oid_copy_in_addr(name
+ v
->namelen
, area_id
);
1896 oid_copy_in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
,
1904 static uint8_t *ospfVirtIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1905 int exact
, size_t *var_len
,
1906 WriteMethod
**write_method
)
1908 struct ospf_vl_data
*vl_data
;
1909 struct ospf_interface
*oi
;
1910 struct in_addr area_id
;
1911 struct in_addr neighbor
;
1913 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1917 memset(&area_id
, 0, sizeof(area_id
));
1918 memset(&neighbor
, 0, sizeof(neighbor
));
1920 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
1923 oi
= vl_data
->vl_oi
;
1927 /* Return the current value of the variable */
1929 case OSPFVIRTIFAREAID
:
1930 return SNMP_IPADDRESS(area_id
);
1931 case OSPFVIRTIFNEIGHBOR
:
1932 return SNMP_IPADDRESS(neighbor
);
1933 case OSPFVIRTIFTRANSITDELAY
:
1934 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1935 case OSPFVIRTIFRETRANSINTERVAL
:
1936 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1937 case OSPFVIRTIFHELLOINTERVAL
:
1938 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1939 case OSPFVIRTIFRTRDEADINTERVAL
:
1940 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1941 case OSPFVIRTIFSTATE
:
1942 return SNMP_INTEGER(oi
->state
);
1943 case OSPFVIRTIFEVENTS
:
1944 return SNMP_INTEGER(oi
->state_change
);
1945 case OSPFVIRTIFAUTHKEY
:
1947 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1948 case OSPFVIRTIFSTATUS
:
1949 return SNMP_INTEGER(SNMP_VALID
);
1950 case OSPFVIRTIFAUTHTYPE
:
1952 return SNMP_INTEGER(oi
->area
->auth_type
);
1954 return SNMP_INTEGER(0);
1961 static struct ospf_neighbor
*ospf_snmp_nbr_lookup(struct ospf
*ospf
,
1962 struct in_addr
*nbr_addr
,
1965 struct listnode
*node
, *nnode
;
1966 struct ospf_interface
*oi
;
1967 struct ospf_neighbor
*nbr
;
1968 struct route_node
*rn
;
1970 for (ALL_LIST_ELEMENTS(ospf
->oiflist
, node
, nnode
, oi
)) {
1971 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
1972 if ((nbr
= rn
->info
) != NULL
1973 && nbr
!= oi
->nbr_self
1974 /* If EXACT match is needed, provide ALL entry found
1975 && nbr->state != NSM_Down
1977 && nbr
->src
.s_addr
!= INADDR_ANY
) {
1978 if (IPV4_ADDR_SAME(&nbr
->src
, nbr_addr
)) {
1979 route_unlock_node(rn
);
1987 static struct ospf_neighbor
*ospf_snmp_nbr_lookup_next(struct in_addr
*nbr_addr
,
1991 struct listnode
*nn
;
1992 struct ospf_interface
*oi
;
1993 struct ospf_neighbor
*nbr
;
1994 struct route_node
*rn
;
1995 struct ospf_neighbor
*min
= NULL
;
1998 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2000 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, nn
, oi
)) {
2001 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2002 if ((nbr
= rn
->info
) != NULL
&& nbr
!= oi
->nbr_self
2003 && nbr
->state
!= NSM_Down
2004 && nbr
->src
.s_addr
!= INADDR_ANY
) {
2008 else if (ntohl(nbr
->src
.s_addr
)
2009 < ntohl(min
->src
.s_addr
))
2011 } else if (ntohl(nbr
->src
.s_addr
)
2012 > ntohl(nbr_addr
->s_addr
)) {
2015 else if (ntohl(nbr
->src
.s_addr
)
2016 < ntohl(min
->src
.s_addr
))
2022 *nbr_addr
= min
->src
;
2029 static struct ospf_neighbor
*ospfNbrLookup(struct variable
*v
, oid
*name
,
2031 struct in_addr
*nbr_addr
,
2032 ifindex_t
*ifindex
, int exact
)
2036 struct ospf_neighbor
*nbr
;
2039 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2045 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
2048 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, nbr_addr
);
2049 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2051 return ospf_snmp_nbr_lookup(ospf
, nbr_addr
, ifindex
);
2054 len
= *length
- v
->namelen
;
2059 if (len
> IN_ADDR_SIZE
)
2062 oid2in_addr(name
+ v
->namelen
, len
, nbr_addr
);
2064 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
2066 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2068 nbr
= ospf_snmp_nbr_lookup_next(nbr_addr
, ifindex
, first
);
2071 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
2072 oid_copy_in_addr(name
+ v
->namelen
, nbr_addr
);
2073 name
[v
->namelen
+ IN_ADDR_SIZE
] = *ifindex
;
2080 /* map internal frr neighbor states to official MIB values:
2082 ospfNbrState OBJECT-TYPE
2094 static int32_t ospf_snmp_neighbor_state(uint8_t nst
)
2112 return 1; /* down */
2116 static uint8_t *ospfNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2117 int exact
, size_t *var_len
,
2118 WriteMethod
**write_method
)
2120 struct in_addr nbr_addr
;
2122 struct ospf_neighbor
*nbr
;
2123 struct ospf_interface
*oi
;
2125 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2129 memset(&nbr_addr
, 0, sizeof(nbr_addr
));
2132 nbr
= ospfNbrLookup(v
, name
, length
, &nbr_addr
, &ifindex
, exact
);
2137 /* Return the current value of the variable */
2140 return SNMP_IPADDRESS(nbr_addr
);
2141 case OSPFNBRADDRESSLESSINDEX
:
2142 return SNMP_INTEGER(ifindex
);
2144 return SNMP_IPADDRESS(nbr
->router_id
);
2145 case OSPFNBROPTIONS
:
2146 return SNMP_INTEGER(oi
->nbr_self
->options
);
2147 case OSPFNBRPRIORITY
:
2148 return SNMP_INTEGER(nbr
->priority
);
2150 return SNMP_INTEGER(ospf_snmp_neighbor_state(nbr
->state
));
2152 return SNMP_INTEGER(nbr
->state_change
);
2153 case OSPFNBRLSRETRANSQLEN
:
2154 return SNMP_INTEGER(ospf_ls_retransmit_count(nbr
));
2155 case OSPFNBMANBRSTATUS
:
2156 return SNMP_INTEGER(SNMP_VALID
);
2157 case OSPFNBMANBRPERMANENCE
:
2158 return SNMP_INTEGER(2);
2159 case OSPFNBRHELLOSUPPRESSED
:
2160 return SNMP_INTEGER(SNMP_FALSE
);
2167 static uint8_t *ospfVirtNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2168 int exact
, size_t *var_len
,
2169 WriteMethod
**write_method
)
2171 struct ospf_vl_data
*vl_data
;
2172 struct in_addr area_id
;
2173 struct in_addr neighbor
;
2176 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2180 memset(&area_id
, 0, sizeof(area_id
));
2181 memset(&neighbor
, 0, sizeof(neighbor
));
2183 /* Check OSPF instance. */
2184 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2188 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
2192 /* Return the current value of the variable */
2194 case OSPFVIRTNBRAREA
:
2195 return (uint8_t *)NULL
;
2196 case OSPFVIRTNBRRTRID
:
2197 return (uint8_t *)NULL
;
2198 case OSPFVIRTNBRIPADDR
:
2199 return (uint8_t *)NULL
;
2200 case OSPFVIRTNBROPTIONS
:
2201 return (uint8_t *)NULL
;
2202 case OSPFVIRTNBRSTATE
:
2203 return (uint8_t *)NULL
;
2204 case OSPFVIRTNBREVENTS
:
2205 return (uint8_t *)NULL
;
2206 case OSPFVIRTNBRLSRETRANSQLEN
:
2207 return (uint8_t *)NULL
;
2208 case OSPFVIRTNBRHELLOSUPPRESSED
:
2209 return (uint8_t *)NULL
;
2216 static struct ospf_lsa
*ospfExtLsdbLookup(struct variable
*v
, oid
*name
,
2217 size_t *length
, uint8_t *type
,
2218 struct in_addr
*ls_id
,
2219 struct in_addr
*router_id
, int exact
)
2226 struct ospf_lsa
*lsa
;
2229 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2231 if (*length
!= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
2234 offset
= name
+ v
->namelen
;
2236 /* Make it sure given value match to type. */
2240 if (lsa_type
!= *type
)
2244 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
2245 offset
+= IN_ADDR_SIZE
;
2248 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
2250 return ospf_lsdb_lookup_by_id(ospf
->lsdb
, *type
, *ls_id
,
2253 /* Get variable length. */
2255 offset
= name
+ v
->namelen
;
2256 offsetlen
= *length
- v
->namelen
;
2258 /* LSA type value. */
2263 if (offsetlen
<= 0 || lsa_type
< OSPF_AS_EXTERNAL_LSA
)
2268 if (len
> IN_ADDR_SIZE
)
2271 oid2in_addr(offset
, len
, ls_id
);
2273 offset
+= IN_ADDR_SIZE
;
2274 offsetlen
-= IN_ADDR_SIZE
;
2278 if (len
> IN_ADDR_SIZE
)
2281 oid2in_addr(offset
, len
, router_id
);
2283 lsa
= ospf_lsdb_lookup_by_id_next(ospf
->lsdb
, *type
, *ls_id
,
2287 /* Fill in length. */
2288 *length
= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
2290 /* Fill in value. */
2291 offset
= name
+ v
->namelen
;
2293 *offset
= OSPF_AS_EXTERNAL_LSA
;
2295 oid_copy_in_addr(offset
, &lsa
->data
->id
);
2296 offset
+= IN_ADDR_SIZE
;
2297 oid_copy_in_addr(offset
, &lsa
->data
->adv_router
);
2305 static uint8_t *ospfExtLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
2306 int exact
, size_t *var_len
,
2307 WriteMethod
**write_method
)
2309 struct ospf_lsa
*lsa
;
2310 struct lsa_header
*lsah
;
2312 struct in_addr ls_id
;
2313 struct in_addr router_id
;
2316 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2320 type
= OSPF_AS_EXTERNAL_LSA
;
2321 memset(&ls_id
, 0, sizeof(ls_id
));
2322 memset(&router_id
, 0, sizeof(router_id
));
2324 /* Check OSPF instance. */
2325 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2329 lsa
= ospfExtLsdbLookup(v
, name
, length
, &type
, &ls_id
, &router_id
,
2336 /* Return the current value of the variable */
2338 case OSPFEXTLSDBTYPE
:
2339 return SNMP_INTEGER(OSPF_AS_EXTERNAL_LSA
);
2340 case OSPFEXTLSDBLSID
:
2341 return SNMP_IPADDRESS(lsah
->id
);
2342 case OSPFEXTLSDBROUTERID
:
2343 return SNMP_IPADDRESS(lsah
->adv_router
);
2344 case OSPFEXTLSDBSEQUENCE
:
2345 return SNMP_INTEGER(lsah
->ls_seqnum
);
2346 case OSPFEXTLSDBAGE
:
2347 return SNMP_INTEGER(lsah
->ls_age
);
2348 case OSPFEXTLSDBCHECKSUM
:
2349 return SNMP_INTEGER(lsah
->checksum
);
2350 case OSPFEXTLSDBADVERTISEMENT
:
2351 *var_len
= ntohs(lsah
->length
);
2352 return (uint8_t *)lsah
;
2359 static uint8_t *ospfAreaAggregateEntry(struct variable
*v
, oid
*name
,
2360 size_t *length
, int exact
,
2362 WriteMethod
**write_method
)
2364 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2368 /* Return the current value of the variable */
2370 case OSPFAREAAGGREGATEAREAID
:
2371 return (uint8_t *)NULL
;
2372 case OSPFAREAAGGREGATELSDBTYPE
:
2373 return (uint8_t *)NULL
;
2374 case OSPFAREAAGGREGATENET
:
2375 return (uint8_t *)NULL
;
2376 case OSPFAREAAGGREGATEMASK
:
2377 return (uint8_t *)NULL
;
2378 case OSPFAREAAGGREGATESTATUS
:
2379 return (uint8_t *)NULL
;
2380 case OSPFAREAAGGREGATEEFFECT
:
2381 return (uint8_t *)NULL
;
2389 #define IFSTATECHANGE 16
2390 #define VIRTIFSTATECHANGE 1
2391 #define NBRSTATECHANGE 2
2392 #define VIRTNBRSTATECHANGE 3
2394 static struct trap_object ospfNbrTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2395 {3, {10, 1, OSPFNBRIPADDR
}},
2396 {3, {10, 1, OSPFNBRRTRID
}},
2397 {3, {10, 1, OSPFNBRSTATE
}}};
2400 static struct trap_object ospfVirtNbrTrapList
[] = {
2402 {3, {11, 1, OSPFVIRTNBRAREA
}},
2403 {3, {11, 1, OSPFVIRTNBRRTRID
}},
2404 {3, {11, 1, OSPFVIRTNBRSTATE
}}};
2406 static struct trap_object ospfIfTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2407 {3, {7, 1, OSPFIFIPADDRESS
}},
2408 {3, {7, 1, OSPFADDRESSLESSIF
}},
2409 {3, {7, 1, OSPFIFSTATE
}}};
2411 static struct trap_object ospfVirtIfTrapList
[] = {
2412 {-2, {1, OSPFROUTERID
}},
2413 {3, {9, 1, OSPFVIRTIFAREAID
}},
2414 {3, {9, 1, OSPFVIRTIFNEIGHBOR
}},
2415 {3, {9, 1, OSPFVIRTIFSTATE
}}};
2417 static void ospfTrapNbrStateChange(struct ospf_neighbor
*on
)
2419 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2422 ospf_nbr_ism_state_message(on
, msgbuf
, sizeof(msgbuf
));
2423 if (IS_DEBUG_OSPF_EVENT
)
2424 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2425 &on
->address
.u
.prefix4
, msgbuf
);
2427 oid_copy_in_addr(index
, &(on
->address
.u
.prefix4
));
2428 index
[IN_ADDR_SIZE
] = 0;
2430 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2431 array_size(ospf_trap_oid
), ospf_oid
,
2432 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2433 ospfNbrTrapList
, array_size(ospfNbrTrapList
), NBRSTATECHANGE
);
2436 static void ospfTrapVirtNbrStateChange(struct ospf_neighbor
*on
)
2438 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2440 zlog_info("ospfTrapVirtNbrStateChange trap sent");
2442 oid_copy_in_addr(index
, &(on
->address
.u
.prefix4
));
2443 index
[IN_ADDR_SIZE
] = 0;
2445 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2446 array_size(ospf_trap_oid
), ospf_oid
,
2447 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2448 ospfVirtNbrTrapList
, array_size(ospfVirtNbrTrapList
),
2449 VIRTNBRSTATECHANGE
);
2452 static int ospf_snmp_nsm_change(struct ospf_neighbor
*nbr
, int next_state
,
2455 /* Transition to/from state Full should be handled only by
2456 * DR when in Broadcast or Non-Brodcast Multi-Access networks
2458 if ((next_state
== NSM_Full
|| old_state
== NSM_Full
)
2459 && (nbr
->oi
->state
!= ISM_DR
)
2460 && (nbr
->oi
->type
== OSPF_IFTYPE_BROADCAST
2461 || nbr
->oi
->type
== OSPF_IFTYPE_NBMA
))
2464 /* State progression to non-terminal state */
2465 if (next_state
> old_state
&& next_state
!= NSM_Full
2466 && next_state
!= NSM_TwoWay
)
2469 if (nbr
->oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2470 ospfTrapVirtNbrStateChange(nbr
);
2472 ospfTrapNbrStateChange(nbr
);
2477 static void ospfTrapIfStateChange(struct ospf_interface
*oi
)
2479 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2481 if (IS_DEBUG_OSPF_EVENT
)
2482 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2483 &oi
->address
->u
.prefix4
,
2484 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
2486 oid_copy_in_addr(index
, &(oi
->address
->u
.prefix4
));
2487 index
[IN_ADDR_SIZE
] = 0;
2489 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2490 array_size(ospf_trap_oid
), ospf_oid
,
2491 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2492 ospfIfTrapList
, array_size(ospfIfTrapList
), IFSTATECHANGE
);
2495 static void ospfTrapVirtIfStateChange(struct ospf_interface
*oi
)
2497 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2499 zlog_info("ospfTrapVirtIfStateChange trap sent");
2501 oid_copy_in_addr(index
, &(oi
->address
->u
.prefix4
));
2502 index
[IN_ADDR_SIZE
] = 0;
2504 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2505 array_size(ospf_trap_oid
), ospf_oid
,
2506 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2507 ospfVirtIfTrapList
, array_size(ospfVirtIfTrapList
),
2511 static int ospf_snmp_ism_change(struct ospf_interface
*oi
, int state
,
2514 /* Terminal state or regression */
2515 if ((state
== ISM_DR
) || (state
== ISM_Backup
) || (state
== ISM_DROther
)
2516 || (state
== ISM_PointToPoint
) || (state
< old_state
)) {
2517 /* ospfVirtIfStateChange */
2518 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2519 ospfTrapVirtIfStateChange(oi
);
2520 /* ospfIfStateChange */
2522 ospfTrapIfStateChange(oi
);
2527 /* Register OSPF2-MIB. */
2528 static int ospf_snmp_init(struct event_loop
*tm
)
2530 ospf_snmp_iflist
= list_new();
2531 ospf_snmp_vl_table
= route_table_init();
2533 REGISTER_MIB("mibII/ospf", ospf_variables
, variable
, ospf_oid
);
2537 static int ospf_snmp_module_init(void)
2539 hook_register(ospf_if_update
, ospf_snmp_if_update
);
2540 hook_register(ospf_if_delete
, ospf_snmp_if_delete
);
2541 hook_register(ospf_vl_add
, ospf_snmp_vl_add
);
2542 hook_register(ospf_vl_delete
, ospf_snmp_vl_delete
);
2543 hook_register(ospf_ism_change
, ospf_snmp_ism_change
);
2544 hook_register(ospf_nsm_change
, ospf_snmp_nsm_change
);
2546 hook_register(frr_late_init
, ospf_snmp_init
);
2550 FRR_MODULE_SETUP(.name
= "ospfd_snmp", .version
= FRR_VERSION
,
2551 .description
= "ospfd AgentX SNMP module",
2552 .init
= ospf_snmp_module_init
,