2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 2000 IP Infusion Inc.
5 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
7 * This file is part of GNU Zebra.
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <net-snmp/net-snmp-config.h>
27 #include <net-snmp/net-snmp-includes.h>
37 #include "lib/version.h"
39 #include "ospfd/ospfd.h"
40 #include "ospfd/ospf_interface.h"
41 #include "ospfd/ospf_asbr.h"
42 #include "ospfd/ospf_lsa.h"
43 #include "ospfd/ospf_lsdb.h"
44 #include "ospfd/ospf_abr.h"
45 #include "ospfd/ospf_neighbor.h"
46 #include "ospfd/ospf_nsm.h"
47 #include "ospfd/ospf_flood.h"
48 #include "ospfd/ospf_ism.h"
49 #include "ospfd/ospf_dump.h"
50 #include "ospfd/ospf_route.h"
51 #include "ospfd/ospf_zebra.h"
53 DEFINE_MTYPE_STATIC(OSPFD
, SNMP
, "OSPF SNMP");
56 #define OSPF2MIB 1,3,6,1,2,1,14
58 /* OSPF MIB General Group values. */
59 #define OSPFROUTERID 1
60 #define OSPFADMINSTAT 2
61 #define OSPFVERSIONNUMBER 3
62 #define OSPFAREABDRRTRSTATUS 4
63 #define OSPFASBDRRTRSTATUS 5
64 #define OSPFEXTERNLSACOUNT 6
65 #define OSPFEXTERNLSACKSUMSUM 7
66 #define OSPFTOSSUPPORT 8
67 #define OSPFORIGINATENEWLSAS 9
68 #define OSPFRXNEWLSAS 10
69 #define OSPFEXTLSDBLIMIT 11
70 #define OSPFMULTICASTEXTENSIONS 12
71 #define OSPFEXITOVERFLOWINTERVAL 13
72 #define OSPFDEMANDEXTENSIONS 14
74 /* OSPF MIB ospfAreaTable. */
76 #define OSPFAUTHTYPE 2
77 #define OSPFIMPORTASEXTERN 3
79 #define OSPFAREABDRRTRCOUNT 5
80 #define OSPFASBDRRTRCOUNT 6
81 #define OSPFAREALSACOUNT 7
82 #define OSPFAREALSACKSUMSUM 8
83 #define OSPFAREASUMMARY 9
84 #define OSPFAREASTATUS 10
86 /* OSPF MIB ospfStubAreaTable. */
87 #define OSPFSTUBAREAID 1
89 #define OSPFSTUBMETRIC 3
90 #define OSPFSTUBSTATUS 4
91 #define OSPFSTUBMETRICTYPE 5
93 /* OSPF MIB ospfLsdbTable. */
94 #define OSPFLSDBAREAID 1
95 #define OSPFLSDBTYPE 2
96 #define OSPFLSDBLSID 3
97 #define OSPFLSDBROUTERID 4
98 #define OSPFLSDBSEQUENCE 5
100 #define OSPFLSDBCHECKSUM 7
101 #define OSPFLSDBADVERTISEMENT 8
103 /* OSPF MIB ospfAreaRangeTable. */
104 #define OSPFAREARANGEAREAID 1
105 #define OSPFAREARANGENET 2
106 #define OSPFAREARANGEMASK 3
107 #define OSPFAREARANGESTATUS 4
108 #define OSPFAREARANGEEFFECT 5
110 /* OSPF MIB ospfHostTable. */
111 #define OSPFHOSTIPADDRESS 1
112 #define OSPFHOSTTOS 2
113 #define OSPFHOSTMETRIC 3
114 #define OSPFHOSTSTATUS 4
115 #define OSPFHOSTAREAID 5
117 /* OSPF MIB ospfIfTable. */
118 #define OSPFIFIPADDRESS 1
119 #define OSPFADDRESSLESSIF 2
120 #define OSPFIFAREAID 3
122 #define OSPFIFADMINSTAT 5
123 #define OSPFIFRTRPRIORITY 6
124 #define OSPFIFTRANSITDELAY 7
125 #define OSPFIFRETRANSINTERVAL 8
126 #define OSPFIFHELLOINTERVAL 9
127 #define OSPFIFRTRDEADINTERVAL 10
128 #define OSPFIFPOLLINTERVAL 11
129 #define OSPFIFSTATE 12
130 #define OSPFIFDESIGNATEDROUTER 13
131 #define OSPFIFBACKUPDESIGNATEDROUTER 14
132 #define OSPFIFEVENTS 15
133 #define OSPFIFAUTHKEY 16
134 #define OSPFIFSTATUS 17
135 #define OSPFIFMULTICASTFORWARDING 18
136 #define OSPFIFDEMAND 19
137 #define OSPFIFAUTHTYPE 20
139 /* OSPF MIB ospfIfMetricTable. */
140 #define OSPFIFMETRICIPADDRESS 1
141 #define OSPFIFMETRICADDRESSLESSIF 2
142 #define OSPFIFMETRICTOS 3
143 #define OSPFIFMETRICVALUE 4
144 #define OSPFIFMETRICSTATUS 5
146 /* OSPF MIB ospfVirtIfTable. */
147 #define OSPFVIRTIFAREAID 1
148 #define OSPFVIRTIFNEIGHBOR 2
149 #define OSPFVIRTIFTRANSITDELAY 3
150 #define OSPFVIRTIFRETRANSINTERVAL 4
151 #define OSPFVIRTIFHELLOINTERVAL 5
152 #define OSPFVIRTIFRTRDEADINTERVAL 6
153 #define OSPFVIRTIFSTATE 7
154 #define OSPFVIRTIFEVENTS 8
155 #define OSPFVIRTIFAUTHKEY 9
156 #define OSPFVIRTIFSTATUS 10
157 #define OSPFVIRTIFAUTHTYPE 11
159 /* OSPF MIB ospfNbrTable. */
160 #define OSPFNBRIPADDR 1
161 #define OSPFNBRADDRESSLESSINDEX 2
162 #define OSPFNBRRTRID 3
163 #define OSPFNBROPTIONS 4
164 #define OSPFNBRPRIORITY 5
165 #define OSPFNBRSTATE 6
166 #define OSPFNBREVENTS 7
167 #define OSPFNBRLSRETRANSQLEN 8
168 #define OSPFNBMANBRSTATUS 9
169 #define OSPFNBMANBRPERMANENCE 10
170 #define OSPFNBRHELLOSUPPRESSED 11
172 /* OSPF MIB ospfVirtNbrTable. */
173 #define OSPFVIRTNBRAREA 1
174 #define OSPFVIRTNBRRTRID 2
175 #define OSPFVIRTNBRIPADDR 3
176 #define OSPFVIRTNBROPTIONS 4
177 #define OSPFVIRTNBRSTATE 5
178 #define OSPFVIRTNBREVENTS 6
179 #define OSPFVIRTNBRLSRETRANSQLEN 7
180 #define OSPFVIRTNBRHELLOSUPPRESSED 8
182 /* OSPF MIB ospfExtLsdbTable. */
183 #define OSPFEXTLSDBTYPE 1
184 #define OSPFEXTLSDBLSID 2
185 #define OSPFEXTLSDBROUTERID 3
186 #define OSPFEXTLSDBSEQUENCE 4
187 #define OSPFEXTLSDBAGE 5
188 #define OSPFEXTLSDBCHECKSUM 6
189 #define OSPFEXTLSDBADVERTISEMENT 7
191 /* OSPF MIB ospfAreaAggregateTable. */
192 #define OSPFAREAAGGREGATEAREAID 1
193 #define OSPFAREAAGGREGATELSDBTYPE 2
194 #define OSPFAREAAGGREGATENET 3
195 #define OSPFAREAAGGREGATEMASK 4
196 #define OSPFAREAAGGREGATESTATUS 5
197 #define OSPFAREAAGGREGATEEFFECT 6
199 /* SYNTAX Status from OSPF-MIB. */
200 #define OSPF_STATUS_ENABLED 1
201 #define OSPF_STATUS_DISABLED 2
203 /* SNMP value hack. */
204 #define COUNTER ASN_COUNTER
205 #define INTEGER ASN_INTEGER
206 #define GAUGE ASN_GAUGE
207 #define TIMETICKS ASN_TIMETICKS
208 #define IPADDRESS ASN_IPADDRESS
209 #define STRING ASN_OCTET_STR
211 /* Because DR/DROther values are exhanged wrt RFC */
212 #define ISM_SNMP(x) \
213 (((x) == ISM_DROther) ? ISM_DR : ((x) == ISM_DR) ? ISM_DROther : (x))
215 /* Declare static local variables for convenience. */
218 /* OSPF-MIB instances. */
219 static oid ospf_oid
[] = {OSPF2MIB
};
220 static oid ospf_trap_oid
[] = {OSPF2MIB
, 16, 2}; /* Not reverse mappable! */
222 /* IP address 0.0.0.0. */
223 static struct in_addr ospf_empty_addr
= {.s_addr
= 0};
225 /* Hook functions. */
226 static uint8_t *ospfGeneralGroup(struct variable
*, oid
*, size_t *, int,
227 size_t *, WriteMethod
**);
228 static uint8_t *ospfAreaEntry(struct variable
*, oid
*, size_t *, int, size_t *,
230 static uint8_t *ospfStubAreaEntry(struct variable
*, oid
*, size_t *, int,
231 size_t *, WriteMethod
**);
232 static uint8_t *ospfLsdbEntry(struct variable
*, oid
*, size_t *, int, size_t *,
234 static uint8_t *ospfAreaRangeEntry(struct variable
*, oid
*, size_t *, int,
235 size_t *, WriteMethod
**);
236 static uint8_t *ospfHostEntry(struct variable
*, oid
*, size_t *, int, size_t *,
238 static uint8_t *ospfIfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
240 static uint8_t *ospfIfMetricEntry(struct variable
*, oid
*, size_t *, int,
241 size_t *, WriteMethod
**);
242 static uint8_t *ospfVirtIfEntry(struct variable
*, oid
*, size_t *, int,
243 size_t *, WriteMethod
**);
244 static uint8_t *ospfNbrEntry(struct variable
*, oid
*, size_t *, int, size_t *,
246 static uint8_t *ospfVirtNbrEntry(struct variable
*, oid
*, size_t *, int,
247 size_t *, WriteMethod
**);
248 static uint8_t *ospfExtLsdbEntry(struct variable
*, oid
*, size_t *, int,
249 size_t *, WriteMethod
**);
250 static uint8_t *ospfAreaAggregateEntry(struct variable
*, oid
*, size_t *, int,
251 size_t *, WriteMethod
**);
253 static struct variable ospf_variables
[] = {
254 /* OSPF general variables */
255 {OSPFROUTERID
, IPADDRESS
, RWRITE
, ospfGeneralGroup
, 2, {1, 1}},
256 {OSPFADMINSTAT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 2}},
257 {OSPFVERSIONNUMBER
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 3}},
258 {OSPFAREABDRRTRSTATUS
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 4}},
259 {OSPFASBDRRTRSTATUS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 5}},
260 {OSPFEXTERNLSACOUNT
, GAUGE
, RONLY
, ospfGeneralGroup
, 2, {1, 6}},
261 {OSPFEXTERNLSACKSUMSUM
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 7}},
262 {OSPFTOSSUPPORT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 8}},
263 {OSPFORIGINATENEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 9}},
264 {OSPFRXNEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 10}},
265 {OSPFEXTLSDBLIMIT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 11}},
266 {OSPFMULTICASTEXTENSIONS
,
272 {OSPFEXITOVERFLOWINTERVAL
,
278 {OSPFDEMANDEXTENSIONS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 14}},
280 /* OSPF area data structure. */
281 {OSPFAREAID
, IPADDRESS
, RONLY
, ospfAreaEntry
, 3, {2, 1, 1}},
282 {OSPFAUTHTYPE
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 2}},
283 {OSPFIMPORTASEXTERN
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 3}},
284 {OSPFSPFRUNS
, COUNTER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 4}},
285 {OSPFAREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 5}},
286 {OSPFASBDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 6}},
287 {OSPFAREALSACOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 7}},
288 {OSPFAREALSACKSUMSUM
, INTEGER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 8}},
289 {OSPFAREASUMMARY
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 9}},
290 {OSPFAREASTATUS
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 10}},
292 /* OSPF stub area information. */
293 {OSPFSTUBAREAID
, IPADDRESS
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 1}},
294 {OSPFSTUBTOS
, INTEGER
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 2}},
295 {OSPFSTUBMETRIC
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 3}},
296 {OSPFSTUBSTATUS
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 4}},
297 {OSPFSTUBMETRICTYPE
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 5}},
299 /* OSPF link state database. */
300 {OSPFLSDBAREAID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 1}},
301 {OSPFLSDBTYPE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 2}},
302 {OSPFLSDBLSID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 3}},
303 {OSPFLSDBROUTERID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 4}},
304 {OSPFLSDBSEQUENCE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 5}},
305 {OSPFLSDBAGE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 6}},
306 {OSPFLSDBCHECKSUM
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 7}},
307 {OSPFLSDBADVERTISEMENT
, STRING
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 8}},
309 /* Area range table. */
310 {OSPFAREARANGEAREAID
,
316 {OSPFAREARANGENET
, IPADDRESS
, RONLY
, ospfAreaRangeEntry
, 3, {5, 1, 2}},
323 {OSPFAREARANGESTATUS
,
329 {OSPFAREARANGEEFFECT
,
336 /* OSPF host table. */
337 {OSPFHOSTIPADDRESS
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 1}},
338 {OSPFHOSTTOS
, INTEGER
, RONLY
, ospfHostEntry
, 3, {6, 1, 2}},
339 {OSPFHOSTMETRIC
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 3}},
340 {OSPFHOSTSTATUS
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 4}},
341 {OSPFHOSTAREAID
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 5}},
343 /* OSPF interface table. */
344 {OSPFIFIPADDRESS
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 1}},
345 {OSPFADDRESSLESSIF
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 2}},
346 {OSPFIFAREAID
, IPADDRESS
, RWRITE
, ospfIfEntry
, 3, {7, 1, 3}},
347 {OSPFIFTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 4}},
348 {OSPFIFADMINSTAT
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 5}},
349 {OSPFIFRTRPRIORITY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 6}},
350 {OSPFIFTRANSITDELAY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 7}},
351 {OSPFIFRETRANSINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 8}},
352 {OSPFIFHELLOINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 9}},
353 {OSPFIFRTRDEADINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 10}},
354 {OSPFIFPOLLINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 11}},
355 {OSPFIFSTATE
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 12}},
356 {OSPFIFDESIGNATEDROUTER
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 13}},
357 {OSPFIFBACKUPDESIGNATEDROUTER
,
363 {OSPFIFEVENTS
, COUNTER
, RONLY
, ospfIfEntry
, 3, {7, 1, 15}},
364 {OSPFIFAUTHKEY
, STRING
, RWRITE
, ospfIfEntry
, 3, {7, 1, 16}},
365 {OSPFIFSTATUS
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 17}},
366 {OSPFIFMULTICASTFORWARDING
,
372 {OSPFIFDEMAND
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 19}},
373 {OSPFIFAUTHTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 20}},
375 /* OSPF interface metric table. */
376 {OSPFIFMETRICIPADDRESS
,
382 {OSPFIFMETRICADDRESSLESSIF
,
388 {OSPFIFMETRICTOS
, INTEGER
, RONLY
, ospfIfMetricEntry
, 3, {8, 1, 3}},
389 {OSPFIFMETRICVALUE
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 4}},
390 {OSPFIFMETRICSTATUS
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 5}},
392 /* OSPF virtual interface table. */
393 {OSPFVIRTIFAREAID
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 1}},
394 {OSPFVIRTIFNEIGHBOR
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 2}},
395 {OSPFVIRTIFTRANSITDELAY
,
401 {OSPFVIRTIFRETRANSINTERVAL
,
407 {OSPFVIRTIFHELLOINTERVAL
,
413 {OSPFVIRTIFRTRDEADINTERVAL
,
419 {OSPFVIRTIFSTATE
, INTEGER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 7}},
420 {OSPFVIRTIFEVENTS
, COUNTER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 8}},
421 {OSPFVIRTIFAUTHKEY
, STRING
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 9}},
422 {OSPFVIRTIFSTATUS
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 10}},
423 {OSPFVIRTIFAUTHTYPE
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 11}},
425 /* OSPF neighbor table. */
426 {OSPFNBRIPADDR
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 1}},
427 {OSPFNBRADDRESSLESSINDEX
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 2}},
428 {OSPFNBRRTRID
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 3}},
429 {OSPFNBROPTIONS
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 4}},
430 {OSPFNBRPRIORITY
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 5}},
431 {OSPFNBRSTATE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 6}},
432 {OSPFNBREVENTS
, COUNTER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 7}},
433 {OSPFNBRLSRETRANSQLEN
, GAUGE
, RONLY
, ospfNbrEntry
, 3, {10, 1, 8}},
434 {OSPFNBMANBRSTATUS
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 9}},
435 {OSPFNBMANBRPERMANENCE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 10}},
436 {OSPFNBRHELLOSUPPRESSED
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 11}},
438 /* OSPF virtual neighbor table. */
439 {OSPFVIRTNBRAREA
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 1}},
440 {OSPFVIRTNBRRTRID
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 2}},
441 {OSPFVIRTNBRIPADDR
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 3}},
442 {OSPFVIRTNBROPTIONS
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 4}},
443 {OSPFVIRTNBRSTATE
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 5}},
444 {OSPFVIRTNBREVENTS
, COUNTER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 6}},
445 {OSPFVIRTNBRLSRETRANSQLEN
,
451 {OSPFVIRTNBRHELLOSUPPRESSED
,
458 /* OSPF link state database, external. */
459 {OSPFEXTLSDBTYPE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 1}},
460 {OSPFEXTLSDBLSID
, IPADDRESS
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 2}},
461 {OSPFEXTLSDBROUTERID
,
467 {OSPFEXTLSDBSEQUENCE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 4}},
468 {OSPFEXTLSDBAGE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 5}},
469 {OSPFEXTLSDBCHECKSUM
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 6}},
470 {OSPFEXTLSDBADVERTISEMENT
,
477 /* OSPF area aggregate table. */
478 {OSPFAREAAGGREGATEAREAID
,
481 ospfAreaAggregateEntry
,
484 {OSPFAREAAGGREGATELSDBTYPE
,
487 ospfAreaAggregateEntry
,
490 {OSPFAREAAGGREGATENET
,
493 ospfAreaAggregateEntry
,
496 {OSPFAREAAGGREGATEMASK
,
499 ospfAreaAggregateEntry
,
502 {OSPFAREAAGGREGATESTATUS
,
505 ospfAreaAggregateEntry
,
508 {OSPFAREAAGGREGATEEFFECT
,
511 ospfAreaAggregateEntry
,
515 /* The administrative status of OSPF. When OSPF is enbled on at least
516 one interface return 1. */
517 static int ospf_admin_stat(struct ospf
*ospf
)
519 struct listnode
*node
;
520 struct ospf_interface
*oi
;
525 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
526 if (oi
&& oi
->address
)
532 static uint8_t *ospfGeneralGroup(struct variable
*v
, oid
*name
, size_t *length
,
533 int exact
, size_t *var_len
,
534 WriteMethod
**write_method
)
538 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
540 /* Check whether the instance identifier is valid */
541 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
545 /* Return the current value of the variable */
547 case OSPFROUTERID
: /* 1 */
548 /* Router-ID of this OSPF instance. */
550 return SNMP_IPADDRESS(ospf
->router_id
);
552 return SNMP_IPADDRESS(ospf_empty_addr
);
553 case OSPFADMINSTAT
: /* 2 */
554 /* The administrative status of OSPF in the router. */
555 if (ospf_admin_stat(ospf
))
556 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
558 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
559 case OSPFVERSIONNUMBER
: /* 3 */
560 /* OSPF version 2. */
561 return SNMP_INTEGER(OSPF_VERSION
);
562 case OSPFAREABDRRTRSTATUS
: /* 4 */
563 /* Area Border router status. */
564 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ABR
))
565 return SNMP_INTEGER(SNMP_TRUE
);
567 return SNMP_INTEGER(SNMP_FALSE
);
568 case OSPFASBDRRTRSTATUS
: /* 5 */
569 /* AS Border router status. */
570 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ASBR
))
571 return SNMP_INTEGER(SNMP_TRUE
);
573 return SNMP_INTEGER(SNMP_FALSE
);
574 case OSPFEXTERNLSACOUNT
: /* 6 */
575 /* External LSA counts. */
577 return SNMP_INTEGER(ospf_lsdb_count_all(ospf
->lsdb
));
579 return SNMP_INTEGER(0);
580 case OSPFEXTERNLSACKSUMSUM
: /* 7 */
581 /* External LSA checksum. */
582 return SNMP_INTEGER(0);
583 case OSPFTOSSUPPORT
: /* 8 */
584 /* TOS is not supported. */
585 return SNMP_INTEGER(SNMP_FALSE
);
586 case OSPFORIGINATENEWLSAS
: /* 9 */
587 /* The number of new link-state advertisements. */
589 return SNMP_INTEGER(ospf
->lsa_originate_count
);
591 return SNMP_INTEGER(0);
592 case OSPFRXNEWLSAS
: /* 10 */
593 /* The number of link-state advertisements received determined
594 to be new instantiations. */
596 return SNMP_INTEGER(ospf
->rx_lsa_count
);
598 return SNMP_INTEGER(0);
599 case OSPFEXTLSDBLIMIT
: /* 11 */
600 /* There is no limit for the number of non-default
602 return SNMP_INTEGER(-1);
603 case OSPFMULTICASTEXTENSIONS
: /* 12 */
604 /* Multicast Extensions to OSPF is not supported. */
605 return SNMP_INTEGER(0);
606 case OSPFEXITOVERFLOWINTERVAL
: /* 13 */
607 /* Overflow is not supported. */
608 return SNMP_INTEGER(0);
609 case OSPFDEMANDEXTENSIONS
: /* 14 */
610 /* Demand routing is not supported. */
611 return SNMP_INTEGER(SNMP_FALSE
);
618 static struct ospf_area
*
619 ospf_area_lookup_next(struct ospf
*ospf
, struct in_addr
*area_id
, int first
)
621 struct ospf_area
*area
;
622 struct listnode
*node
;
628 node
= listhead(ospf
->areas
);
630 area
= listgetdata(node
);
631 *area_id
= area
->area_id
;
636 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
637 if (ntohl(area
->area_id
.s_addr
) > ntohl(area_id
->s_addr
)) {
638 *area_id
= area
->area_id
;
645 static struct ospf_area
*ospfAreaLookup(struct variable
*v
, oid name
[],
646 size_t *length
, struct in_addr
*addr
,
650 struct ospf_area
*area
;
653 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
658 /* Length is insufficient to lookup OSPF area. */
659 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
662 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
664 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
668 len
= *length
- v
->namelen
;
672 oid2in_addr(name
+ v
->namelen
, len
, addr
);
674 area
= ospf_area_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
679 oid_copy_in_addr(name
+ v
->namelen
, addr
);
680 *length
= sizeof(struct in_addr
) + v
->namelen
;
687 static uint8_t *ospfAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
688 int exact
, size_t *var_len
,
689 WriteMethod
**write_method
)
691 struct ospf_area
*area
;
694 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
698 memset(&addr
, 0, sizeof(addr
));
700 area
= ospfAreaLookup(v
, name
, length
, &addr
, exact
);
704 /* Return the current value of the variable */
706 case OSPFAREAID
: /* 1 */
707 return SNMP_IPADDRESS(area
->area_id
);
708 case OSPFAUTHTYPE
: /* 2 */
709 return SNMP_INTEGER(area
->auth_type
);
710 case OSPFIMPORTASEXTERN
: /* 3 */
711 return SNMP_INTEGER(area
->external_routing
+ 1);
712 case OSPFSPFRUNS
: /* 4 */
713 return SNMP_INTEGER(area
->spf_calculation
);
714 case OSPFAREABDRRTRCOUNT
: /* 5 */
715 return SNMP_INTEGER(area
->abr_count
);
716 case OSPFASBDRRTRCOUNT
: /* 6 */
717 return SNMP_INTEGER(area
->asbr_count
);
718 case OSPFAREALSACOUNT
: /* 7 */
719 return SNMP_INTEGER(area
->lsdb
->total
);
720 case OSPFAREALSACKSUMSUM
: /* 8 */
721 return SNMP_INTEGER(0);
722 case OSPFAREASUMMARY
: /* 9 */
723 #define OSPF_noAreaSummary 1
724 #define OSPF_sendAreaSummary 2
725 if (area
->no_summary
)
726 return SNMP_INTEGER(OSPF_noAreaSummary
);
728 return SNMP_INTEGER(OSPF_sendAreaSummary
);
729 case OSPFAREASTATUS
: /* 10 */
730 return SNMP_INTEGER(SNMP_VALID
);
737 static struct ospf_area
*ospf_stub_area_lookup_next(struct in_addr
*area_id
,
740 struct ospf_area
*area
;
741 struct listnode
*node
;
744 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
748 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
749 if (area
->external_routing
== OSPF_AREA_STUB
) {
751 *area_id
= area
->area_id
;
753 } else if (ntohl(area
->area_id
.s_addr
)
754 > ntohl(area_id
->s_addr
)) {
755 *area_id
= area
->area_id
;
763 static struct ospf_area
*ospfStubAreaLookup(struct variable
*v
, oid name
[],
765 struct in_addr
*addr
, int exact
)
768 struct ospf_area
*area
;
771 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
777 /* ospfStubAreaID + ospfStubTOS. */
778 if (*length
!= v
->namelen
+ sizeof(struct in_addr
) + 1)
781 /* Check ospfStubTOS is zero. */
782 if (name
[*length
- 1] != 0)
785 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
787 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
789 if (area
&& area
->external_routing
== OSPF_AREA_STUB
)
794 len
= *length
- v
->namelen
;
798 oid2in_addr(name
+ v
->namelen
, len
, addr
);
800 area
= ospf_stub_area_lookup_next(addr
, len
== 0 ? 1 : 0);
805 oid_copy_in_addr(name
+ v
->namelen
, addr
);
807 name
[v
->namelen
+ sizeof(struct in_addr
)] = 0;
808 *length
= v
->namelen
+ sizeof(struct in_addr
) + 1;
815 static uint8_t *ospfStubAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
816 int exact
, size_t *var_len
,
817 WriteMethod
**write_method
)
819 struct ospf_area
*area
;
822 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
826 memset(&addr
, 0, sizeof(addr
));
828 area
= ospfStubAreaLookup(v
, name
, length
, &addr
, exact
);
832 /* Return the current value of the variable */
834 case OSPFSTUBAREAID
: /* 1 */
835 /* OSPF stub area id. */
836 return SNMP_IPADDRESS(area
->area_id
);
837 case OSPFSTUBTOS
: /* 2 */
838 /* TOS value is not supported. */
839 return SNMP_INTEGER(0);
840 case OSPFSTUBMETRIC
: /* 3 */
841 /* Default cost to stub area. */
842 return SNMP_INTEGER(area
->default_cost
);
843 case OSPFSTUBSTATUS
: /* 4 */
844 /* Status of the stub area. */
845 return SNMP_INTEGER(SNMP_VALID
);
846 case OSPFSTUBMETRICTYPE
: /* 5 */
847 /* OSPF Metric type. */
848 #define OSPF_ospfMetric 1
849 #define OSPF_comparableCost 2
850 #define OSPF_nonComparable 3
851 return SNMP_INTEGER(OSPF_ospfMetric
);
858 static struct ospf_lsa
*lsdb_lookup_next(struct ospf_area
*area
, uint8_t *type
,
859 int type_next
, struct in_addr
*ls_id
,
861 struct in_addr
*router_id
,
864 struct ospf_lsa
*lsa
;
872 /* Sanity check, if LSA type unknwon
873 merley skip any LSA */
874 if ((i
< OSPF_MIN_LSA
) || (i
>= OSPF_MAX_LSA
)) {
875 zlog_debug("Strange request with LSA type %d", i
);
879 for (; i
< OSPF_MAX_LSA
; i
++) {
882 lsa
= ospf_lsdb_lookup_by_id_next(area
->lsdb
, *type
, *ls_id
,
883 *router_id
, ls_id_next
);
892 static struct ospf_lsa
*ospfLsdbLookup(struct variable
*v
, oid
*name
,
893 size_t *length
, struct in_addr
*area_id
,
894 uint8_t *type
, struct in_addr
*ls_id
,
895 struct in_addr
*router_id
, int exact
)
898 struct ospf_area
*area
;
899 struct ospf_lsa
*lsa
;
907 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
909 #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
912 /* Area ID + Type + LS ID + Router ID. */
913 if (*length
- v
->namelen
!= OSPF_LSDB_ENTRY_OFFSET
)
916 /* Set OID offset for Area ID. */
917 offset
= name
+ v
->namelen
;
919 /* Lookup area first. */
920 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
921 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
924 offset
+= IN_ADDR_SIZE
;
931 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
932 offset
+= IN_ADDR_SIZE
;
935 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
938 return ospf_lsdb_lookup_by_id(area
->lsdb
, *type
, *ls_id
,
941 /* Get variable length. */
942 offset
= name
+ v
->namelen
;
943 offsetlen
= *length
- v
->namelen
;
946 if (len
> (int)IN_ADDR_SIZE
)
949 oid2in_addr(offset
, len
, area_id
);
951 /* First we search area. */
952 if (len
== IN_ADDR_SIZE
)
953 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
955 area
= ospf_area_lookup_next(ospf
, area_id
, 1);
961 /* Next we lookup type. */
982 if (len
> (int)IN_ADDR_SIZE
)
985 oid2in_addr(offset
, len
, ls_id
);
989 offset
+= IN_ADDR_SIZE
;
990 offsetlen
-= IN_ADDR_SIZE
;
997 if (len
> (int)IN_ADDR_SIZE
)
1000 oid2in_addr(offset
, len
, router_id
);
1003 lsa
= lsdb_lookup_next(area
, type
, type_next
, ls_id
,
1004 ls_id_next
, router_id
,
1008 /* Fill in length. */
1009 *length
= v
->namelen
+ OSPF_LSDB_ENTRY_OFFSET
;
1011 /* Fill in value. */
1012 offset
= name
+ v
->namelen
;
1013 oid_copy_in_addr(offset
, area_id
);
1014 offset
+= IN_ADDR_SIZE
;
1015 *offset
= lsa
->data
->type
;
1017 oid_copy_in_addr(offset
, &lsa
->data
->id
);
1018 offset
+= IN_ADDR_SIZE
;
1019 oid_copy_in_addr(offset
,
1020 &lsa
->data
->adv_router
);
1024 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1030 static uint8_t *ospfLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
1031 int exact
, size_t *var_len
,
1032 WriteMethod
**write_method
)
1034 struct ospf_lsa
*lsa
;
1035 struct lsa_header
*lsah
;
1036 struct in_addr area_id
;
1038 struct in_addr ls_id
;
1039 struct in_addr router_id
;
1042 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1046 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1047 ospfLsdbLsid, ospfLsdbRouterId } */
1049 memset(&area_id
, 0, sizeof(area_id
));
1051 memset(&ls_id
, 0, sizeof(ls_id
));
1052 memset(&router_id
, 0, sizeof(router_id
));
1054 /* Check OSPF instance. */
1055 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1059 lsa
= ospfLsdbLookup(v
, name
, length
, &area_id
, &type
, &ls_id
,
1066 /* Return the current value of the variable */
1068 case OSPFLSDBAREAID
: /* 1 */
1069 return SNMP_IPADDRESS(lsa
->area
->area_id
);
1070 case OSPFLSDBTYPE
: /* 2 */
1071 return SNMP_INTEGER(lsah
->type
);
1072 case OSPFLSDBLSID
: /* 3 */
1073 return SNMP_IPADDRESS(lsah
->id
);
1074 case OSPFLSDBROUTERID
: /* 4 */
1075 return SNMP_IPADDRESS(lsah
->adv_router
);
1076 case OSPFLSDBSEQUENCE
: /* 5 */
1077 return SNMP_INTEGER(lsah
->ls_seqnum
);
1078 case OSPFLSDBAGE
: /* 6 */
1079 return SNMP_INTEGER(lsah
->ls_age
);
1080 case OSPFLSDBCHECKSUM
: /* 7 */
1081 return SNMP_INTEGER(lsah
->checksum
);
1082 case OSPFLSDBADVERTISEMENT
: /* 8 */
1083 *var_len
= ntohs(lsah
->length
);
1084 return (uint8_t *)lsah
;
1091 static struct ospf_area_range
*ospfAreaRangeLookup(struct variable
*v
,
1092 oid
*name
, size_t *length
,
1093 struct in_addr
*area_id
,
1094 struct in_addr
*range_net
,
1101 struct ospf_area
*area
;
1102 struct ospf_area_range
*range
;
1103 struct prefix_ipv4 p
;
1105 p
.prefixlen
= IPV4_MAX_BITLEN
;
1107 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1110 /* Area ID + Range Network. */
1111 if (v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
!= *length
)
1114 /* Set OID offset for Area ID. */
1115 offset
= name
+ v
->namelen
;
1117 /* Lookup area first. */
1118 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
1120 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1124 offset
+= IN_ADDR_SIZE
;
1126 /* Lookup area range. */
1127 oid2in_addr(offset
, IN_ADDR_SIZE
, range_net
);
1128 p
.prefix
= *range_net
;
1130 return ospf_area_range_lookup(area
, &p
);
1132 /* Set OID offset for Area ID. */
1133 offset
= name
+ v
->namelen
;
1134 offsetlen
= *length
- v
->namelen
;
1137 if (len
> (int)IN_ADDR_SIZE
)
1140 oid2in_addr(offset
, len
, area_id
);
1142 /* First we search area. */
1143 if (len
== IN_ADDR_SIZE
)
1144 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1146 area
= ospf_area_lookup_next(ospf
, area_id
,
1153 offset
+= IN_ADDR_SIZE
;
1154 offsetlen
-= IN_ADDR_SIZE
;
1159 if (len
> (int)IN_ADDR_SIZE
)
1162 oid2in_addr(offset
, len
, range_net
);
1164 range
= ospf_area_range_lookup_next(area
, range_net
,
1168 /* Fill in length. */
1169 *length
= v
->namelen
+ IN_ADDR_SIZE
1172 /* Fill in value. */
1173 offset
= name
+ v
->namelen
;
1174 oid_copy_in_addr(offset
, area_id
);
1175 offset
+= IN_ADDR_SIZE
;
1176 oid_copy_in_addr(offset
, range_net
);
1180 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1186 static uint8_t *ospfAreaRangeEntry(struct variable
*v
, oid
*name
,
1187 size_t *length
, int exact
, size_t *var_len
,
1188 WriteMethod
**write_method
)
1190 struct ospf_area_range
*range
;
1191 struct in_addr area_id
;
1192 struct in_addr range_net
;
1193 struct in_addr mask
;
1196 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1200 /* Check OSPF instance. */
1201 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1205 memset(&area_id
, 0, IN_ADDR_SIZE
);
1206 memset(&range_net
, 0, IN_ADDR_SIZE
);
1208 range
= ospfAreaRangeLookup(v
, name
, length
, &area_id
, &range_net
,
1213 /* Convert prefixlen to network mask format. */
1214 masklen2ip(range
->subst_masklen
, &mask
);
1216 /* Return the current value of the variable */
1218 case OSPFAREARANGEAREAID
: /* 1 */
1219 return SNMP_IPADDRESS(area_id
);
1220 case OSPFAREARANGENET
: /* 2 */
1221 return SNMP_IPADDRESS(range_net
);
1222 case OSPFAREARANGEMASK
: /* 3 */
1223 return SNMP_IPADDRESS(mask
);
1224 case OSPFAREARANGESTATUS
: /* 4 */
1225 return SNMP_INTEGER(SNMP_VALID
);
1226 case OSPFAREARANGEEFFECT
: /* 5 */
1227 #define OSPF_advertiseMatching 1
1228 #define OSPF_doNotAdvertiseMatching 2
1229 return SNMP_INTEGER(OSPF_advertiseMatching
);
1236 static struct ospf_nbr_nbma
*ospfHostLookup(struct variable
*v
, oid
*name
,
1238 struct in_addr
*addr
, int exact
)
1240 struct ospf_nbr_nbma
*nbr_nbma
;
1243 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1248 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1249 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1252 /* Check ospfHostTOS. */
1253 if (name
[*length
- 1] != 0)
1256 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, addr
);
1258 nbr_nbma
= ospf_nbr_nbma_lookup(ospf
, *addr
);
1266 static uint8_t *ospfHostEntry(struct variable
*v
, oid
*name
, size_t *length
,
1267 int exact
, size_t *var_len
,
1268 WriteMethod
**write_method
)
1270 struct ospf_nbr_nbma
*nbr_nbma
;
1271 struct ospf_interface
*oi
;
1272 struct in_addr addr
;
1275 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1279 /* Check OSPF instance. */
1280 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1284 memset(&addr
, 0, sizeof(addr
));
1286 nbr_nbma
= ospfHostLookup(v
, name
, length
, &addr
, exact
);
1287 if (nbr_nbma
== NULL
)
1292 /* Return the current value of the variable */
1294 case OSPFHOSTIPADDRESS
: /* 1 */
1295 return SNMP_IPADDRESS(nbr_nbma
->addr
);
1296 case OSPFHOSTTOS
: /* 2 */
1297 return SNMP_INTEGER(0);
1298 case OSPFHOSTMETRIC
: /* 3 */
1300 return SNMP_INTEGER(oi
->output_cost
);
1302 return SNMP_INTEGER(1);
1303 case OSPFHOSTSTATUS
: /* 4 */
1304 return SNMP_INTEGER(SNMP_VALID
);
1305 case OSPFHOSTAREAID
: /* 5 */
1307 return SNMP_IPADDRESS(oi
->area
->area_id
);
1309 return SNMP_IPADDRESS(ospf_empty_addr
);
1316 static struct list
*ospf_snmp_iflist
;
1318 struct ospf_snmp_if
{
1319 struct in_addr addr
;
1321 struct interface
*ifp
;
1324 static struct ospf_snmp_if
*ospf_snmp_if_new(void)
1326 return XCALLOC(MTYPE_SNMP
, sizeof(struct ospf_snmp_if
));
1329 static void ospf_snmp_if_free(struct ospf_snmp_if
*osif
)
1331 XFREE(MTYPE_SNMP
, osif
);
1334 static int ospf_snmp_if_delete(struct interface
*ifp
)
1336 struct listnode
*node
, *nnode
;
1337 struct ospf_snmp_if
*osif
;
1339 for (ALL_LIST_ELEMENTS(ospf_snmp_iflist
, node
, nnode
, osif
)) {
1340 if (osif
->ifp
== ifp
) {
1341 list_delete_node(ospf_snmp_iflist
, node
);
1342 ospf_snmp_if_free(osif
);
1349 static int ospf_snmp_if_update(struct interface
*ifp
)
1351 struct listnode
*node
;
1352 struct listnode
*pn
;
1353 struct connected
*ifc
;
1355 struct ospf_snmp_if
*osif
;
1356 struct in_addr
*addr
;
1359 ospf_snmp_if_delete(ifp
);
1365 /* Lookup first IPv4 address entry. */
1366 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1367 p
= CONNECTED_ID(ifc
);
1369 if (p
->family
== AF_INET
) {
1370 addr
= &p
->u
.prefix4
;
1375 ifindex
= ifp
->ifindex
;
1377 /* Add interface to the list. */
1379 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1381 /* Usual interfaces --> Sort them based on interface
1383 if (ntohl(osif
->addr
.s_addr
) > ntohl(addr
->s_addr
))
1386 /* Unnumbered interfaces --> Sort them based on
1387 * interface indexes */
1388 if (osif
->addr
.s_addr
!= INADDR_ANY
1389 || osif
->ifindex
> ifindex
)
1395 osif
= ospf_snmp_if_new();
1396 if (addr
) /* Usual interface */
1400 /* This field is used for storing ospfAddressLessIf OID value,
1401 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1402 * usual interface */
1404 } else /* Unnumbered interface */
1405 osif
->ifindex
= ifindex
;
1408 listnode_add_after(ospf_snmp_iflist
, pn
, osif
);
1412 static int ospf_snmp_is_if_have_addr(struct interface
*ifp
)
1414 struct listnode
*nn
;
1415 struct connected
*ifc
;
1417 /* Is this interface having any connected IPv4 address ? */
1418 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, nn
, ifc
)) {
1419 if (CONNECTED_PREFIX(ifc
)->family
== AF_INET
)
1426 static struct ospf_interface
*ospf_snmp_if_lookup(struct in_addr
*ifaddr
,
1429 struct listnode
*node
;
1430 struct ospf_snmp_if
*osif
;
1431 struct ospf_interface
*oi
= NULL
;
1432 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1434 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1435 if (ifaddr
->s_addr
) {
1436 if (IPV4_ADDR_SAME(&osif
->addr
, ifaddr
))
1437 oi
= ospf_if_lookup_by_local_addr(
1438 ospf
, osif
->ifp
, *ifaddr
);
1440 if (osif
->ifindex
== *ifindex
)
1441 oi
= ospf_if_lookup_by_local_addr(
1442 ospf
, osif
->ifp
, *ifaddr
);
1448 static struct ospf_interface
*ospf_snmp_if_lookup_next(struct in_addr
*ifaddr
,
1451 ifindex_t ifindex_next
)
1453 struct ospf_snmp_if
*osif
;
1454 struct listnode
*nn
;
1455 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1456 struct ospf_interface
*oi
= NULL
;
1461 /* No instance is specified --> Return the first OSPF interface */
1463 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1464 osif
= listgetdata(nn
);
1465 *ifaddr
= osif
->addr
;
1466 *ifindex
= osif
->ifindex
;
1467 /* Because no instance is specified, we don't care about
1469 * interface (usual or unnumbered), just returning the
1472 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1480 /* An instance is specified --> Return the next OSPF interface */
1481 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1482 /* Usual interface */
1483 if (ifaddr
->s_addr
) {
1484 /* The interface must have valid AF_INET connected
1486 /* it must have lager IPv4 address value than the lookup
1488 if ((ospf_snmp_is_if_have_addr(osif
->ifp
))
1489 && (ntohl(osif
->addr
.s_addr
)
1490 > ntohl(ifaddr
->s_addr
))) {
1491 *ifaddr
= osif
->addr
;
1492 *ifindex
= osif
->ifindex
;
1494 /* and it must be an OSPF interface */
1495 oi
= ospf_if_lookup_by_local_addr(
1496 ospf
, osif
->ifp
, *ifaddr
);
1501 /* Unnumbered interface */
1503 /* The interface must NOT have valid AF_INET connected
1505 /* it must have lager interface index than the lookup
1507 if ((!ospf_snmp_is_if_have_addr(osif
->ifp
))
1508 && (osif
->ifindex
> *ifindex
)) {
1509 *ifaddr
= osif
->addr
;
1510 *ifindex
= osif
->ifindex
;
1512 /* and it must be an OSPF interface */
1513 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1522 static int ospf_snmp_iftype(struct interface
*ifp
)
1524 #define ospf_snmp_iftype_broadcast 1
1525 #define ospf_snmp_iftype_nbma 2
1526 #define ospf_snmp_iftype_pointToPoint 3
1527 #define ospf_snmp_iftype_pointToMultipoint 5
1528 if (if_is_broadcast(ifp
))
1529 return ospf_snmp_iftype_broadcast
;
1530 if (if_is_pointopoint(ifp
))
1531 return ospf_snmp_iftype_pointToPoint
;
1532 return ospf_snmp_iftype_broadcast
;
1535 static struct ospf_interface
*ospfIfLookup(struct variable
*v
, oid
*name
,
1537 struct in_addr
*ifaddr
,
1538 ifindex_t
*ifindex
, int exact
)
1541 int ifaddr_next
= 0;
1542 ifindex_t ifindex_next
= 0;
1543 struct ospf_interface
*oi
;
1547 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1550 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1551 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1553 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1555 len
= *length
- v
->namelen
;
1556 if (len
>= IN_ADDR_SIZE
)
1561 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1563 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1570 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1572 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1575 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1576 offset
= name
+ v
->namelen
;
1577 oid_copy_in_addr(offset
, ifaddr
);
1578 offset
+= IN_ADDR_SIZE
;
1586 static uint8_t *ospfIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1587 int exact
, size_t *var_len
,
1588 WriteMethod
**write_method
)
1591 struct in_addr ifaddr
;
1592 struct ospf_interface
*oi
;
1595 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1600 memset(&ifaddr
, 0, sizeof(ifaddr
));
1602 /* Check OSPF instance. */
1603 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1607 oi
= ospfIfLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1611 /* Return the current value of the variable */
1613 case OSPFIFIPADDRESS
: /* 1 */
1614 return SNMP_IPADDRESS(ifaddr
);
1615 case OSPFADDRESSLESSIF
: /* 2 */
1616 return SNMP_INTEGER(ifindex
);
1617 case OSPFIFAREAID
: /* 3 */
1619 return SNMP_IPADDRESS(oi
->area
->area_id
);
1621 return SNMP_IPADDRESS(ospf_empty_addr
);
1622 case OSPFIFTYPE
: /* 4 */
1623 return SNMP_INTEGER(ospf_snmp_iftype(oi
->ifp
));
1624 case OSPFIFADMINSTAT
: /* 5 */
1626 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1628 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1629 case OSPFIFRTRPRIORITY
: /* 6 */
1630 return SNMP_INTEGER(PRIORITY(oi
));
1631 case OSPFIFTRANSITDELAY
: /* 7 */
1632 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1633 case OSPFIFRETRANSINTERVAL
: /* 8 */
1634 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1635 case OSPFIFHELLOINTERVAL
: /* 9 */
1636 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1637 case OSPFIFRTRDEADINTERVAL
: /* 10 */
1638 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1639 case OSPFIFPOLLINTERVAL
: /* 11 */
1640 return SNMP_INTEGER(OSPF_POLL_INTERVAL_DEFAULT
);
1641 case OSPFIFSTATE
: /* 12 */
1642 return SNMP_INTEGER(ISM_SNMP(oi
->state
));
1643 case OSPFIFDESIGNATEDROUTER
: /* 13 */
1644 return SNMP_IPADDRESS(DR(oi
));
1645 case OSPFIFBACKUPDESIGNATEDROUTER
: /* 14 */
1646 return SNMP_IPADDRESS(BDR(oi
));
1647 case OSPFIFEVENTS
: /* 15 */
1648 return SNMP_INTEGER(oi
->state_change
);
1649 case OSPFIFAUTHKEY
: /* 16 */
1651 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1652 case OSPFIFSTATUS
: /* 17 */
1653 return SNMP_INTEGER(SNMP_VALID
);
1654 case OSPFIFMULTICASTFORWARDING
: /* 18 */
1655 #define ospf_snmp_multiforward_blocked 1
1656 #define ospf_snmp_multiforward_multicast 2
1657 #define ospf_snmp_multiforward_unicast 3
1658 return SNMP_INTEGER(ospf_snmp_multiforward_blocked
);
1659 case OSPFIFDEMAND
: /* 19 */
1660 return SNMP_INTEGER(SNMP_FALSE
);
1661 case OSPFIFAUTHTYPE
: /* 20 */
1663 return SNMP_INTEGER(oi
->area
->auth_type
);
1665 return SNMP_INTEGER(0);
1672 #define OSPF_SNMP_METRIC_VALUE 1
1674 static struct ospf_interface
*ospfIfMetricLookup(struct variable
*v
, oid
*name
,
1676 struct in_addr
*ifaddr
,
1677 ifindex_t
*ifindex
, int exact
)
1680 int ifaddr_next
= 0;
1681 ifindex_t ifindex_next
= 0;
1682 struct ospf_interface
*oi
;
1687 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1)
1690 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1691 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1692 metric
= name
[v
->namelen
+ IN_ADDR_SIZE
+ 1];
1694 if (metric
!= OSPF_SNMP_METRIC_VALUE
)
1697 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1699 len
= *length
- v
->namelen
;
1700 if (len
>= IN_ADDR_SIZE
)
1705 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1707 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1714 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1716 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1719 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1;
1720 offset
= name
+ v
->namelen
;
1721 oid_copy_in_addr(offset
, ifaddr
);
1722 offset
+= IN_ADDR_SIZE
;
1725 *offset
= OSPF_SNMP_METRIC_VALUE
;
1732 static uint8_t *ospfIfMetricEntry(struct variable
*v
, oid
*name
, size_t *length
,
1733 int exact
, size_t *var_len
,
1734 WriteMethod
**write_method
)
1736 /* Currently we support metric 1 only. */
1738 struct in_addr ifaddr
;
1739 struct ospf_interface
*oi
;
1742 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1747 memset(&ifaddr
, 0, sizeof(ifaddr
));
1749 /* Check OSPF instance. */
1750 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1754 oi
= ospfIfMetricLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1758 /* Return the current value of the variable */
1760 case OSPFIFMETRICIPADDRESS
:
1761 return SNMP_IPADDRESS(ifaddr
);
1762 case OSPFIFMETRICADDRESSLESSIF
:
1763 return SNMP_INTEGER(ifindex
);
1764 case OSPFIFMETRICTOS
:
1765 return SNMP_INTEGER(0);
1766 case OSPFIFMETRICVALUE
:
1767 return SNMP_INTEGER(OSPF_SNMP_METRIC_VALUE
);
1768 case OSPFIFMETRICSTATUS
:
1769 return SNMP_INTEGER(1);
1776 static struct route_table
*ospf_snmp_vl_table
;
1778 static int ospf_snmp_vl_add(struct ospf_vl_data
*vl_data
)
1780 struct prefix_ls lp
;
1781 struct route_node
*rn
;
1783 memset(&lp
, 0, sizeof(lp
));
1784 lp
.family
= AF_UNSPEC
;
1786 lp
.id
= vl_data
->vl_area_id
;
1787 lp
.adv_router
= vl_data
->vl_peer
;
1789 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1791 route_unlock_node(rn
);
1797 static int ospf_snmp_vl_delete(struct ospf_vl_data
*vl_data
)
1799 struct prefix_ls lp
;
1800 struct route_node
*rn
;
1802 memset(&lp
, 0, sizeof(lp
));
1803 lp
.family
= AF_UNSPEC
;
1805 lp
.id
= vl_data
->vl_area_id
;
1806 lp
.adv_router
= vl_data
->vl_peer
;
1808 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1812 route_unlock_node(rn
);
1813 route_unlock_node(rn
);
1817 static struct ospf_vl_data
*ospf_snmp_vl_lookup(struct in_addr
*area_id
,
1818 struct in_addr
*neighbor
)
1820 struct prefix_ls lp
;
1821 struct route_node
*rn
;
1822 struct ospf_vl_data
*vl_data
;
1824 memset(&lp
, 0, sizeof(lp
));
1825 lp
.family
= AF_UNSPEC
;
1828 lp
.adv_router
= *neighbor
;
1830 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1833 route_unlock_node(rn
);
1839 static struct ospf_vl_data
*ospf_snmp_vl_lookup_next(struct in_addr
*area_id
,
1840 struct in_addr
*neighbor
,
1843 struct prefix_ls lp
;
1844 struct route_node
*rn
;
1845 struct ospf_vl_data
*vl_data
;
1847 memset(&lp
, 0, sizeof(lp
));
1848 lp
.family
= AF_UNSPEC
;
1851 lp
.adv_router
= *neighbor
;
1854 rn
= route_top(ospf_snmp_vl_table
);
1856 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1857 rn
= route_next(rn
);
1860 for (; rn
; rn
= route_next(rn
))
1864 if (rn
&& rn
->info
) {
1866 *area_id
= vl_data
->vl_area_id
;
1867 *neighbor
= vl_data
->vl_peer
;
1868 route_unlock_node(rn
);
1874 static struct ospf_vl_data
*
1875 ospfVirtIfLookup(struct variable
*v
, oid
*name
, size_t *length
,
1876 struct in_addr
*area_id
, struct in_addr
*neighbor
, int exact
)
1880 struct ospf_vl_data
*vl_data
;
1883 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
1886 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, area_id
);
1887 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, IN_ADDR_SIZE
,
1890 return ospf_snmp_vl_lookup(area_id
, neighbor
);
1894 len
= *length
- v
->namelen
;
1897 if (len
> IN_ADDR_SIZE
)
1899 oid2in_addr(name
+ v
->namelen
, len
, area_id
);
1901 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1902 if (len
> IN_ADDR_SIZE
)
1904 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, len
, neighbor
);
1906 vl_data
= ospf_snmp_vl_lookup_next(area_id
, neighbor
, first
);
1909 *length
= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
1910 oid_copy_in_addr(name
+ v
->namelen
, area_id
);
1911 oid_copy_in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
,
1919 static uint8_t *ospfVirtIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1920 int exact
, size_t *var_len
,
1921 WriteMethod
**write_method
)
1923 struct ospf_vl_data
*vl_data
;
1924 struct ospf_interface
*oi
;
1925 struct in_addr area_id
;
1926 struct in_addr neighbor
;
1928 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1932 memset(&area_id
, 0, sizeof(area_id
));
1933 memset(&neighbor
, 0, sizeof(neighbor
));
1935 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
1938 oi
= vl_data
->vl_oi
;
1942 /* Return the current value of the variable */
1944 case OSPFVIRTIFAREAID
:
1945 return SNMP_IPADDRESS(area_id
);
1946 case OSPFVIRTIFNEIGHBOR
:
1947 return SNMP_IPADDRESS(neighbor
);
1948 case OSPFVIRTIFTRANSITDELAY
:
1949 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1950 case OSPFVIRTIFRETRANSINTERVAL
:
1951 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1952 case OSPFVIRTIFHELLOINTERVAL
:
1953 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1954 case OSPFVIRTIFRTRDEADINTERVAL
:
1955 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1956 case OSPFVIRTIFSTATE
:
1957 return SNMP_INTEGER(oi
->state
);
1958 case OSPFVIRTIFEVENTS
:
1959 return SNMP_INTEGER(oi
->state_change
);
1960 case OSPFVIRTIFAUTHKEY
:
1962 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1963 case OSPFVIRTIFSTATUS
:
1964 return SNMP_INTEGER(SNMP_VALID
);
1965 case OSPFVIRTIFAUTHTYPE
:
1967 return SNMP_INTEGER(oi
->area
->auth_type
);
1969 return SNMP_INTEGER(0);
1976 static struct ospf_neighbor
*ospf_snmp_nbr_lookup(struct ospf
*ospf
,
1977 struct in_addr
*nbr_addr
,
1980 struct listnode
*node
, *nnode
;
1981 struct ospf_interface
*oi
;
1982 struct ospf_neighbor
*nbr
;
1983 struct route_node
*rn
;
1985 for (ALL_LIST_ELEMENTS(ospf
->oiflist
, node
, nnode
, oi
)) {
1986 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
1987 if ((nbr
= rn
->info
) != NULL
1988 && nbr
!= oi
->nbr_self
1989 /* If EXACT match is needed, provide ALL entry found
1990 && nbr->state != NSM_Down
1992 && nbr
->src
.s_addr
!= INADDR_ANY
) {
1993 if (IPV4_ADDR_SAME(&nbr
->src
, nbr_addr
)) {
1994 route_unlock_node(rn
);
2002 static struct ospf_neighbor
*ospf_snmp_nbr_lookup_next(struct in_addr
*nbr_addr
,
2006 struct listnode
*nn
;
2007 struct ospf_interface
*oi
;
2008 struct ospf_neighbor
*nbr
;
2009 struct route_node
*rn
;
2010 struct ospf_neighbor
*min
= NULL
;
2013 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2015 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, nn
, oi
)) {
2016 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2017 if ((nbr
= rn
->info
) != NULL
&& nbr
!= oi
->nbr_self
2018 && nbr
->state
!= NSM_Down
2019 && nbr
->src
.s_addr
!= INADDR_ANY
) {
2023 else if (ntohl(nbr
->src
.s_addr
)
2024 < ntohl(min
->src
.s_addr
))
2026 } else if (ntohl(nbr
->src
.s_addr
)
2027 > ntohl(nbr_addr
->s_addr
)) {
2030 else if (ntohl(nbr
->src
.s_addr
)
2031 < ntohl(min
->src
.s_addr
))
2037 *nbr_addr
= min
->src
;
2044 static struct ospf_neighbor
*ospfNbrLookup(struct variable
*v
, oid
*name
,
2046 struct in_addr
*nbr_addr
,
2047 ifindex_t
*ifindex
, int exact
)
2051 struct ospf_neighbor
*nbr
;
2054 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2060 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
2063 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, nbr_addr
);
2064 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2066 return ospf_snmp_nbr_lookup(ospf
, nbr_addr
, ifindex
);
2069 len
= *length
- v
->namelen
;
2074 if (len
> IN_ADDR_SIZE
)
2077 oid2in_addr(name
+ v
->namelen
, len
, nbr_addr
);
2079 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
2081 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2083 nbr
= ospf_snmp_nbr_lookup_next(nbr_addr
, ifindex
, first
);
2086 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
2087 oid_copy_in_addr(name
+ v
->namelen
, nbr_addr
);
2088 name
[v
->namelen
+ IN_ADDR_SIZE
] = *ifindex
;
2095 /* map internal frr neighbor states to official MIB values:
2097 ospfNbrState OBJECT-TYPE
2109 static int32_t ospf_snmp_neighbor_state(uint8_t nst
)
2127 return 1; /* down */
2131 static uint8_t *ospfNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2132 int exact
, size_t *var_len
,
2133 WriteMethod
**write_method
)
2135 struct in_addr nbr_addr
;
2137 struct ospf_neighbor
*nbr
;
2138 struct ospf_interface
*oi
;
2140 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2144 memset(&nbr_addr
, 0, sizeof(nbr_addr
));
2147 nbr
= ospfNbrLookup(v
, name
, length
, &nbr_addr
, &ifindex
, exact
);
2152 /* Return the current value of the variable */
2155 return SNMP_IPADDRESS(nbr_addr
);
2156 case OSPFNBRADDRESSLESSINDEX
:
2157 return SNMP_INTEGER(ifindex
);
2159 return SNMP_IPADDRESS(nbr
->router_id
);
2160 case OSPFNBROPTIONS
:
2161 return SNMP_INTEGER(oi
->nbr_self
->options
);
2162 case OSPFNBRPRIORITY
:
2163 return SNMP_INTEGER(nbr
->priority
);
2165 return SNMP_INTEGER(ospf_snmp_neighbor_state(nbr
->state
));
2167 return SNMP_INTEGER(nbr
->state_change
);
2168 case OSPFNBRLSRETRANSQLEN
:
2169 return SNMP_INTEGER(ospf_ls_retransmit_count(nbr
));
2170 case OSPFNBMANBRSTATUS
:
2171 return SNMP_INTEGER(SNMP_VALID
);
2172 case OSPFNBMANBRPERMANENCE
:
2173 return SNMP_INTEGER(2);
2174 case OSPFNBRHELLOSUPPRESSED
:
2175 return SNMP_INTEGER(SNMP_FALSE
);
2182 static uint8_t *ospfVirtNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2183 int exact
, size_t *var_len
,
2184 WriteMethod
**write_method
)
2186 struct ospf_vl_data
*vl_data
;
2187 struct in_addr area_id
;
2188 struct in_addr neighbor
;
2191 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2195 memset(&area_id
, 0, sizeof(area_id
));
2196 memset(&neighbor
, 0, sizeof(neighbor
));
2198 /* Check OSPF instance. */
2199 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2203 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
2207 /* Return the current value of the variable */
2209 case OSPFVIRTNBRAREA
:
2210 return (uint8_t *)NULL
;
2211 case OSPFVIRTNBRRTRID
:
2212 return (uint8_t *)NULL
;
2213 case OSPFVIRTNBRIPADDR
:
2214 return (uint8_t *)NULL
;
2215 case OSPFVIRTNBROPTIONS
:
2216 return (uint8_t *)NULL
;
2217 case OSPFVIRTNBRSTATE
:
2218 return (uint8_t *)NULL
;
2219 case OSPFVIRTNBREVENTS
:
2220 return (uint8_t *)NULL
;
2221 case OSPFVIRTNBRLSRETRANSQLEN
:
2222 return (uint8_t *)NULL
;
2223 case OSPFVIRTNBRHELLOSUPPRESSED
:
2224 return (uint8_t *)NULL
;
2231 static struct ospf_lsa
*ospfExtLsdbLookup(struct variable
*v
, oid
*name
,
2232 size_t *length
, uint8_t *type
,
2233 struct in_addr
*ls_id
,
2234 struct in_addr
*router_id
, int exact
)
2241 struct ospf_lsa
*lsa
;
2244 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2246 if (*length
!= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
2249 offset
= name
+ v
->namelen
;
2251 /* Make it sure given value match to type. */
2255 if (lsa_type
!= *type
)
2259 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
2260 offset
+= IN_ADDR_SIZE
;
2263 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
2265 return ospf_lsdb_lookup_by_id(ospf
->lsdb
, *type
, *ls_id
,
2268 /* Get variable length. */
2270 offset
= name
+ v
->namelen
;
2271 offsetlen
= *length
- v
->namelen
;
2273 /* LSA type value. */
2278 if (offsetlen
<= 0 || lsa_type
< OSPF_AS_EXTERNAL_LSA
)
2283 if (len
> IN_ADDR_SIZE
)
2286 oid2in_addr(offset
, len
, ls_id
);
2288 offset
+= IN_ADDR_SIZE
;
2289 offsetlen
-= IN_ADDR_SIZE
;
2293 if (len
> IN_ADDR_SIZE
)
2296 oid2in_addr(offset
, len
, router_id
);
2298 lsa
= ospf_lsdb_lookup_by_id_next(ospf
->lsdb
, *type
, *ls_id
,
2302 /* Fill in length. */
2303 *length
= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
2305 /* Fill in value. */
2306 offset
= name
+ v
->namelen
;
2308 *offset
= OSPF_AS_EXTERNAL_LSA
;
2310 oid_copy_in_addr(offset
, &lsa
->data
->id
);
2311 offset
+= IN_ADDR_SIZE
;
2312 oid_copy_in_addr(offset
, &lsa
->data
->adv_router
);
2320 static uint8_t *ospfExtLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
2321 int exact
, size_t *var_len
,
2322 WriteMethod
**write_method
)
2324 struct ospf_lsa
*lsa
;
2325 struct lsa_header
*lsah
;
2327 struct in_addr ls_id
;
2328 struct in_addr router_id
;
2331 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2335 type
= OSPF_AS_EXTERNAL_LSA
;
2336 memset(&ls_id
, 0, sizeof(ls_id
));
2337 memset(&router_id
, 0, sizeof(router_id
));
2339 /* Check OSPF instance. */
2340 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2344 lsa
= ospfExtLsdbLookup(v
, name
, length
, &type
, &ls_id
, &router_id
,
2351 /* Return the current value of the variable */
2353 case OSPFEXTLSDBTYPE
:
2354 return SNMP_INTEGER(OSPF_AS_EXTERNAL_LSA
);
2355 case OSPFEXTLSDBLSID
:
2356 return SNMP_IPADDRESS(lsah
->id
);
2357 case OSPFEXTLSDBROUTERID
:
2358 return SNMP_IPADDRESS(lsah
->adv_router
);
2359 case OSPFEXTLSDBSEQUENCE
:
2360 return SNMP_INTEGER(lsah
->ls_seqnum
);
2361 case OSPFEXTLSDBAGE
:
2362 return SNMP_INTEGER(lsah
->ls_age
);
2363 case OSPFEXTLSDBCHECKSUM
:
2364 return SNMP_INTEGER(lsah
->checksum
);
2365 case OSPFEXTLSDBADVERTISEMENT
:
2366 *var_len
= ntohs(lsah
->length
);
2367 return (uint8_t *)lsah
;
2374 static uint8_t *ospfAreaAggregateEntry(struct variable
*v
, oid
*name
,
2375 size_t *length
, int exact
,
2377 WriteMethod
**write_method
)
2379 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2383 /* Return the current value of the variable */
2385 case OSPFAREAAGGREGATEAREAID
:
2386 return (uint8_t *)NULL
;
2387 case OSPFAREAAGGREGATELSDBTYPE
:
2388 return (uint8_t *)NULL
;
2389 case OSPFAREAAGGREGATENET
:
2390 return (uint8_t *)NULL
;
2391 case OSPFAREAAGGREGATEMASK
:
2392 return (uint8_t *)NULL
;
2393 case OSPFAREAAGGREGATESTATUS
:
2394 return (uint8_t *)NULL
;
2395 case OSPFAREAAGGREGATEEFFECT
:
2396 return (uint8_t *)NULL
;
2404 #define IFSTATECHANGE 16
2405 #define VIRTIFSTATECHANGE 1
2406 #define NBRSTATECHANGE 2
2407 #define VIRTNBRSTATECHANGE 3
2409 static struct trap_object ospfNbrTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2410 {3, {10, 1, OSPFNBRIPADDR
}},
2411 {3, {10, 1, OSPFNBRRTRID
}},
2412 {3, {10, 1, OSPFNBRSTATE
}}};
2415 static struct trap_object ospfVirtNbrTrapList
[] = {
2417 {3, {11, 1, OSPFVIRTNBRAREA
}},
2418 {3, {11, 1, OSPFVIRTNBRRTRID
}},
2419 {3, {11, 1, OSPFVIRTNBRSTATE
}}};
2421 static struct trap_object ospfIfTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2422 {3, {7, 1, OSPFIFIPADDRESS
}},
2423 {3, {7, 1, OSPFADDRESSLESSIF
}},
2424 {3, {7, 1, OSPFIFSTATE
}}};
2426 static struct trap_object ospfVirtIfTrapList
[] = {
2427 {-2, {1, OSPFROUTERID
}},
2428 {3, {9, 1, OSPFVIRTIFAREAID
}},
2429 {3, {9, 1, OSPFVIRTIFNEIGHBOR
}},
2430 {3, {9, 1, OSPFVIRTIFSTATE
}}};
2432 static void ospfTrapNbrStateChange(struct ospf_neighbor
*on
)
2434 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2437 ospf_nbr_ism_state_message(on
, msgbuf
, sizeof(msgbuf
));
2438 if (IS_DEBUG_OSPF_EVENT
)
2439 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2440 &on
->address
.u
.prefix4
, msgbuf
);
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 ospfNbrTrapList
, array_size(ospfNbrTrapList
), NBRSTATECHANGE
);
2451 static void ospfTrapVirtNbrStateChange(struct ospf_neighbor
*on
)
2453 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2455 zlog_info("ospfTrapVirtNbrStateChange trap sent");
2457 oid_copy_in_addr(index
, &(on
->address
.u
.prefix4
));
2458 index
[IN_ADDR_SIZE
] = 0;
2460 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2461 array_size(ospf_trap_oid
), ospf_oid
,
2462 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2463 ospfVirtNbrTrapList
, array_size(ospfVirtNbrTrapList
),
2464 VIRTNBRSTATECHANGE
);
2467 static int ospf_snmp_nsm_change(struct ospf_neighbor
*nbr
, int next_state
,
2470 /* Transition to/from state Full should be handled only by
2471 * DR when in Broadcast or Non-Brodcast Multi-Access networks
2473 if ((next_state
== NSM_Full
|| old_state
== NSM_Full
)
2474 && (nbr
->oi
->state
!= ISM_DR
)
2475 && (nbr
->oi
->type
== OSPF_IFTYPE_BROADCAST
2476 || nbr
->oi
->type
== OSPF_IFTYPE_NBMA
))
2479 /* State progression to non-terminal state */
2480 if (next_state
> old_state
&& next_state
!= NSM_Full
2481 && next_state
!= NSM_TwoWay
)
2484 if (nbr
->oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2485 ospfTrapVirtNbrStateChange(nbr
);
2487 ospfTrapNbrStateChange(nbr
);
2492 static void ospfTrapIfStateChange(struct ospf_interface
*oi
)
2494 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2496 if (IS_DEBUG_OSPF_EVENT
)
2497 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2498 &oi
->address
->u
.prefix4
,
2499 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
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 ospfIfTrapList
, array_size(ospfIfTrapList
), IFSTATECHANGE
);
2510 static void ospfTrapVirtIfStateChange(struct ospf_interface
*oi
)
2512 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2514 zlog_info("ospfTrapVirtIfStateChange trap sent");
2516 oid_copy_in_addr(index
, &(oi
->address
->u
.prefix4
));
2517 index
[IN_ADDR_SIZE
] = 0;
2519 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2520 array_size(ospf_trap_oid
), ospf_oid
,
2521 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2522 ospfVirtIfTrapList
, array_size(ospfVirtIfTrapList
),
2526 static int ospf_snmp_ism_change(struct ospf_interface
*oi
, int state
,
2529 /* Terminal state or regression */
2530 if ((state
== ISM_DR
) || (state
== ISM_Backup
) || (state
== ISM_DROther
)
2531 || (state
== ISM_PointToPoint
) || (state
< old_state
)) {
2532 /* ospfVirtIfStateChange */
2533 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2534 ospfTrapVirtIfStateChange(oi
);
2535 /* ospfIfStateChange */
2537 ospfTrapIfStateChange(oi
);
2542 /* Register OSPF2-MIB. */
2543 static int ospf_snmp_init(struct thread_master
*tm
)
2545 ospf_snmp_iflist
= list_new();
2546 ospf_snmp_vl_table
= route_table_init();
2548 REGISTER_MIB("mibII/ospf", ospf_variables
, variable
, ospf_oid
);
2552 static int ospf_snmp_module_init(void)
2554 hook_register(ospf_if_update
, ospf_snmp_if_update
);
2555 hook_register(ospf_if_delete
, ospf_snmp_if_delete
);
2556 hook_register(ospf_vl_add
, ospf_snmp_vl_add
);
2557 hook_register(ospf_vl_delete
, ospf_snmp_vl_delete
);
2558 hook_register(ospf_ism_change
, ospf_snmp_ism_change
);
2559 hook_register(ospf_nsm_change
, ospf_snmp_nsm_change
);
2561 hook_register(frr_late_init
, ospf_snmp_init
);
2565 FRR_MODULE_SETUP(.name
= "ospfd_snmp", .version
= FRR_VERSION
,
2566 .description
= "ospfd AgentX SNMP module",
2567 .init
= ospf_snmp_module_init
,