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>
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"
54 #define OSPF2MIB 1,3,6,1,2,1,14
56 /* OSPF MIB General Group values. */
57 #define OSPFROUTERID 1
58 #define OSPFADMINSTAT 2
59 #define OSPFVERSIONNUMBER 3
60 #define OSPFAREABDRRTRSTATUS 4
61 #define OSPFASBDRRTRSTATUS 5
62 #define OSPFEXTERNLSACOUNT 6
63 #define OSPFEXTERNLSACKSUMSUM 7
64 #define OSPFTOSSUPPORT 8
65 #define OSPFORIGINATENEWLSAS 9
66 #define OSPFRXNEWLSAS 10
67 #define OSPFEXTLSDBLIMIT 11
68 #define OSPFMULTICASTEXTENSIONS 12
69 #define OSPFEXITOVERFLOWINTERVAL 13
70 #define OSPFDEMANDEXTENSIONS 14
72 /* OSPF MIB ospfAreaTable. */
74 #define OSPFAUTHTYPE 2
75 #define OSPFIMPORTASEXTERN 3
77 #define OSPFAREABDRRTRCOUNT 5
78 #define OSPFASBDRRTRCOUNT 6
79 #define OSPFAREALSACOUNT 7
80 #define OSPFAREALSACKSUMSUM 8
81 #define OSPFAREASUMMARY 9
82 #define OSPFAREASTATUS 10
84 /* OSPF MIB ospfStubAreaTable. */
85 #define OSPFSTUBAREAID 1
87 #define OSPFSTUBMETRIC 3
88 #define OSPFSTUBSTATUS 4
89 #define OSPFSTUBMETRICTYPE 5
91 /* OSPF MIB ospfLsdbTable. */
92 #define OSPFLSDBAREAID 1
93 #define OSPFLSDBTYPE 2
94 #define OSPFLSDBLSID 3
95 #define OSPFLSDBROUTERID 4
96 #define OSPFLSDBSEQUENCE 5
98 #define OSPFLSDBCHECKSUM 7
99 #define OSPFLSDBADVERTISEMENT 8
101 /* OSPF MIB ospfAreaRangeTable. */
102 #define OSPFAREARANGEAREAID 1
103 #define OSPFAREARANGENET 2
104 #define OSPFAREARANGEMASK 3
105 #define OSPFAREARANGESTATUS 4
106 #define OSPFAREARANGEEFFECT 5
108 /* OSPF MIB ospfHostTable. */
109 #define OSPFHOSTIPADDRESS 1
110 #define OSPFHOSTTOS 2
111 #define OSPFHOSTMETRIC 3
112 #define OSPFHOSTSTATUS 4
113 #define OSPFHOSTAREAID 5
115 /* OSPF MIB ospfIfTable. */
116 #define OSPFIFIPADDRESS 1
117 #define OSPFADDRESSLESSIF 2
118 #define OSPFIFAREAID 3
120 #define OSPFIFADMINSTAT 5
121 #define OSPFIFRTRPRIORITY 6
122 #define OSPFIFTRANSITDELAY 7
123 #define OSPFIFRETRANSINTERVAL 8
124 #define OSPFIFHELLOINTERVAL 9
125 #define OSPFIFRTRDEADINTERVAL 10
126 #define OSPFIFPOLLINTERVAL 11
127 #define OSPFIFSTATE 12
128 #define OSPFIFDESIGNATEDROUTER 13
129 #define OSPFIFBACKUPDESIGNATEDROUTER 14
130 #define OSPFIFEVENTS 15
131 #define OSPFIFAUTHKEY 16
132 #define OSPFIFSTATUS 17
133 #define OSPFIFMULTICASTFORWARDING 18
134 #define OSPFIFDEMAND 19
135 #define OSPFIFAUTHTYPE 20
137 /* OSPF MIB ospfIfMetricTable. */
138 #define OSPFIFMETRICIPADDRESS 1
139 #define OSPFIFMETRICADDRESSLESSIF 2
140 #define OSPFIFMETRICTOS 3
141 #define OSPFIFMETRICVALUE 4
142 #define OSPFIFMETRICSTATUS 5
144 /* OSPF MIB ospfVirtIfTable. */
145 #define OSPFVIRTIFAREAID 1
146 #define OSPFVIRTIFNEIGHBOR 2
147 #define OSPFVIRTIFTRANSITDELAY 3
148 #define OSPFVIRTIFRETRANSINTERVAL 4
149 #define OSPFVIRTIFHELLOINTERVAL 5
150 #define OSPFVIRTIFRTRDEADINTERVAL 6
151 #define OSPFVIRTIFSTATE 7
152 #define OSPFVIRTIFEVENTS 8
153 #define OSPFVIRTIFAUTHKEY 9
154 #define OSPFVIRTIFSTATUS 10
155 #define OSPFVIRTIFAUTHTYPE 11
157 /* OSPF MIB ospfNbrTable. */
158 #define OSPFNBRIPADDR 1
159 #define OSPFNBRADDRESSLESSINDEX 2
160 #define OSPFNBRRTRID 3
161 #define OSPFNBROPTIONS 4
162 #define OSPFNBRPRIORITY 5
163 #define OSPFNBRSTATE 6
164 #define OSPFNBREVENTS 7
165 #define OSPFNBRLSRETRANSQLEN 8
166 #define OSPFNBMANBRSTATUS 9
167 #define OSPFNBMANBRPERMANENCE 10
168 #define OSPFNBRHELLOSUPPRESSED 11
170 /* OSPF MIB ospfVirtNbrTable. */
171 #define OSPFVIRTNBRAREA 1
172 #define OSPFVIRTNBRRTRID 2
173 #define OSPFVIRTNBRIPADDR 3
174 #define OSPFVIRTNBROPTIONS 4
175 #define OSPFVIRTNBRSTATE 5
176 #define OSPFVIRTNBREVENTS 6
177 #define OSPFVIRTNBRLSRETRANSQLEN 7
178 #define OSPFVIRTNBRHELLOSUPPRESSED 8
180 /* OSPF MIB ospfExtLsdbTable. */
181 #define OSPFEXTLSDBTYPE 1
182 #define OSPFEXTLSDBLSID 2
183 #define OSPFEXTLSDBROUTERID 3
184 #define OSPFEXTLSDBSEQUENCE 4
185 #define OSPFEXTLSDBAGE 5
186 #define OSPFEXTLSDBCHECKSUM 6
187 #define OSPFEXTLSDBADVERTISEMENT 7
189 /* OSPF MIB ospfAreaAggregateTable. */
190 #define OSPFAREAAGGREGATEAREAID 1
191 #define OSPFAREAAGGREGATELSDBTYPE 2
192 #define OSPFAREAAGGREGATENET 3
193 #define OSPFAREAAGGREGATEMASK 4
194 #define OSPFAREAAGGREGATESTATUS 5
195 #define OSPFAREAAGGREGATEEFFECT 6
197 /* SYNTAX Status from OSPF-MIB. */
198 #define OSPF_STATUS_ENABLED 1
199 #define OSPF_STATUS_DISABLED 2
201 /* SNMP value hack. */
202 #define COUNTER ASN_COUNTER
203 #define INTEGER ASN_INTEGER
204 #define GAUGE ASN_GAUGE
205 #define TIMETICKS ASN_TIMETICKS
206 #define IPADDRESS ASN_IPADDRESS
207 #define STRING ASN_OCTET_STR
209 /* Because DR/DROther values are exhanged wrt RFC */
210 #define ISM_SNMP(x) \
211 (((x) == ISM_DROther) ? ISM_DR : ((x) == ISM_DR) ? ISM_DROther : (x))
213 /* Declare static local variables for convenience. */
216 /* OSPF-MIB instances. */
217 static oid ospf_oid
[] = {OSPF2MIB
};
218 static oid ospf_trap_oid
[] = {OSPF2MIB
, 16, 2}; /* Not reverse mappable! */
220 /* IP address 0.0.0.0. */
221 static struct in_addr ospf_empty_addr
= {.s_addr
= 0};
223 /* Hook functions. */
224 static uint8_t *ospfGeneralGroup(struct variable
*, oid
*, size_t *, int,
225 size_t *, WriteMethod
**);
226 static uint8_t *ospfAreaEntry(struct variable
*, oid
*, size_t *, int, size_t *,
228 static uint8_t *ospfStubAreaEntry(struct variable
*, oid
*, size_t *, int,
229 size_t *, WriteMethod
**);
230 static uint8_t *ospfLsdbEntry(struct variable
*, oid
*, size_t *, int, size_t *,
232 static uint8_t *ospfAreaRangeEntry(struct variable
*, oid
*, size_t *, int,
233 size_t *, WriteMethod
**);
234 static uint8_t *ospfHostEntry(struct variable
*, oid
*, size_t *, int, size_t *,
236 static uint8_t *ospfIfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
238 static uint8_t *ospfIfMetricEntry(struct variable
*, oid
*, size_t *, int,
239 size_t *, WriteMethod
**);
240 static uint8_t *ospfVirtIfEntry(struct variable
*, oid
*, size_t *, int,
241 size_t *, WriteMethod
**);
242 static uint8_t *ospfNbrEntry(struct variable
*, oid
*, size_t *, int, size_t *,
244 static uint8_t *ospfVirtNbrEntry(struct variable
*, oid
*, size_t *, int,
245 size_t *, WriteMethod
**);
246 static uint8_t *ospfExtLsdbEntry(struct variable
*, oid
*, size_t *, int,
247 size_t *, WriteMethod
**);
248 static uint8_t *ospfAreaAggregateEntry(struct variable
*, oid
*, size_t *, int,
249 size_t *, WriteMethod
**);
251 static struct variable ospf_variables
[] = {
252 /* OSPF general variables */
253 {OSPFROUTERID
, IPADDRESS
, RWRITE
, ospfGeneralGroup
, 2, {1, 1}},
254 {OSPFADMINSTAT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 2}},
255 {OSPFVERSIONNUMBER
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 3}},
256 {OSPFAREABDRRTRSTATUS
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 4}},
257 {OSPFASBDRRTRSTATUS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 5}},
258 {OSPFEXTERNLSACOUNT
, GAUGE
, RONLY
, ospfGeneralGroup
, 2, {1, 6}},
259 {OSPFEXTERNLSACKSUMSUM
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 7}},
260 {OSPFTOSSUPPORT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 8}},
261 {OSPFORIGINATENEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 9}},
262 {OSPFRXNEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 10}},
263 {OSPFEXTLSDBLIMIT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 11}},
264 {OSPFMULTICASTEXTENSIONS
,
270 {OSPFEXITOVERFLOWINTERVAL
,
276 {OSPFDEMANDEXTENSIONS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 14}},
278 /* OSPF area data structure. */
279 {OSPFAREAID
, IPADDRESS
, RONLY
, ospfAreaEntry
, 3, {2, 1, 1}},
280 {OSPFAUTHTYPE
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 2}},
281 {OSPFIMPORTASEXTERN
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 3}},
282 {OSPFSPFRUNS
, COUNTER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 4}},
283 {OSPFAREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 5}},
284 {OSPFASBDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 6}},
285 {OSPFAREALSACOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 7}},
286 {OSPFAREALSACKSUMSUM
, INTEGER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 8}},
287 {OSPFAREASUMMARY
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 9}},
288 {OSPFAREASTATUS
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 10}},
290 /* OSPF stub area information. */
291 {OSPFSTUBAREAID
, IPADDRESS
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 1}},
292 {OSPFSTUBTOS
, INTEGER
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 2}},
293 {OSPFSTUBMETRIC
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 3}},
294 {OSPFSTUBSTATUS
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 4}},
295 {OSPFSTUBMETRICTYPE
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 5}},
297 /* OSPF link state database. */
298 {OSPFLSDBAREAID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 1}},
299 {OSPFLSDBTYPE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 2}},
300 {OSPFLSDBLSID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 3}},
301 {OSPFLSDBROUTERID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 4}},
302 {OSPFLSDBSEQUENCE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 5}},
303 {OSPFLSDBAGE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 6}},
304 {OSPFLSDBCHECKSUM
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 7}},
305 {OSPFLSDBADVERTISEMENT
, STRING
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 8}},
307 /* Area range table. */
308 {OSPFAREARANGEAREAID
,
314 {OSPFAREARANGENET
, IPADDRESS
, RONLY
, ospfAreaRangeEntry
, 3, {5, 1, 2}},
321 {OSPFAREARANGESTATUS
,
327 {OSPFAREARANGEEFFECT
,
334 /* OSPF host table. */
335 {OSPFHOSTIPADDRESS
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 1}},
336 {OSPFHOSTTOS
, INTEGER
, RONLY
, ospfHostEntry
, 3, {6, 1, 2}},
337 {OSPFHOSTMETRIC
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 3}},
338 {OSPFHOSTSTATUS
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 4}},
339 {OSPFHOSTAREAID
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 5}},
341 /* OSPF interface table. */
342 {OSPFIFIPADDRESS
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 1}},
343 {OSPFADDRESSLESSIF
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 2}},
344 {OSPFIFAREAID
, IPADDRESS
, RWRITE
, ospfIfEntry
, 3, {7, 1, 3}},
345 {OSPFIFTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 4}},
346 {OSPFIFADMINSTAT
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 5}},
347 {OSPFIFRTRPRIORITY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 6}},
348 {OSPFIFTRANSITDELAY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 7}},
349 {OSPFIFRETRANSINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 8}},
350 {OSPFIFHELLOINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 9}},
351 {OSPFIFRTRDEADINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 10}},
352 {OSPFIFPOLLINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 11}},
353 {OSPFIFSTATE
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 12}},
354 {OSPFIFDESIGNATEDROUTER
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 13}},
355 {OSPFIFBACKUPDESIGNATEDROUTER
,
361 {OSPFIFEVENTS
, COUNTER
, RONLY
, ospfIfEntry
, 3, {7, 1, 15}},
362 {OSPFIFAUTHKEY
, STRING
, RWRITE
, ospfIfEntry
, 3, {7, 1, 16}},
363 {OSPFIFSTATUS
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 17}},
364 {OSPFIFMULTICASTFORWARDING
,
370 {OSPFIFDEMAND
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 19}},
371 {OSPFIFAUTHTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 20}},
373 /* OSPF interface metric table. */
374 {OSPFIFMETRICIPADDRESS
,
380 {OSPFIFMETRICADDRESSLESSIF
,
386 {OSPFIFMETRICTOS
, INTEGER
, RONLY
, ospfIfMetricEntry
, 3, {8, 1, 3}},
387 {OSPFIFMETRICVALUE
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 4}},
388 {OSPFIFMETRICSTATUS
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 5}},
390 /* OSPF virtual interface table. */
391 {OSPFVIRTIFAREAID
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 1}},
392 {OSPFVIRTIFNEIGHBOR
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 2}},
393 {OSPFVIRTIFTRANSITDELAY
,
399 {OSPFVIRTIFRETRANSINTERVAL
,
405 {OSPFVIRTIFHELLOINTERVAL
,
411 {OSPFVIRTIFRTRDEADINTERVAL
,
417 {OSPFVIRTIFSTATE
, INTEGER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 7}},
418 {OSPFVIRTIFEVENTS
, COUNTER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 8}},
419 {OSPFVIRTIFAUTHKEY
, STRING
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 9}},
420 {OSPFVIRTIFSTATUS
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 10}},
421 {OSPFVIRTIFAUTHTYPE
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 11}},
423 /* OSPF neighbor table. */
424 {OSPFNBRIPADDR
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 1}},
425 {OSPFNBRADDRESSLESSINDEX
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 2}},
426 {OSPFNBRRTRID
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 3}},
427 {OSPFNBROPTIONS
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 4}},
428 {OSPFNBRPRIORITY
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 5}},
429 {OSPFNBRSTATE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 6}},
430 {OSPFNBREVENTS
, COUNTER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 7}},
431 {OSPFNBRLSRETRANSQLEN
, GAUGE
, RONLY
, ospfNbrEntry
, 3, {10, 1, 8}},
432 {OSPFNBMANBRSTATUS
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 9}},
433 {OSPFNBMANBRPERMANENCE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 10}},
434 {OSPFNBRHELLOSUPPRESSED
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 11}},
436 /* OSPF virtual neighbor table. */
437 {OSPFVIRTNBRAREA
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 1}},
438 {OSPFVIRTNBRRTRID
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 2}},
439 {OSPFVIRTNBRIPADDR
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 3}},
440 {OSPFVIRTNBROPTIONS
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 4}},
441 {OSPFVIRTNBRSTATE
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 5}},
442 {OSPFVIRTNBREVENTS
, COUNTER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 6}},
443 {OSPFVIRTNBRLSRETRANSQLEN
,
449 {OSPFVIRTNBRHELLOSUPPRESSED
,
456 /* OSPF link state database, external. */
457 {OSPFEXTLSDBTYPE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 1}},
458 {OSPFEXTLSDBLSID
, IPADDRESS
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 2}},
459 {OSPFEXTLSDBROUTERID
,
465 {OSPFEXTLSDBSEQUENCE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 4}},
466 {OSPFEXTLSDBAGE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 5}},
467 {OSPFEXTLSDBCHECKSUM
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 6}},
468 {OSPFEXTLSDBADVERTISEMENT
,
475 /* OSPF area aggregate table. */
476 {OSPFAREAAGGREGATEAREAID
,
479 ospfAreaAggregateEntry
,
482 {OSPFAREAAGGREGATELSDBTYPE
,
485 ospfAreaAggregateEntry
,
488 {OSPFAREAAGGREGATENET
,
491 ospfAreaAggregateEntry
,
494 {OSPFAREAAGGREGATEMASK
,
497 ospfAreaAggregateEntry
,
500 {OSPFAREAAGGREGATESTATUS
,
503 ospfAreaAggregateEntry
,
506 {OSPFAREAAGGREGATEEFFECT
,
509 ospfAreaAggregateEntry
,
513 /* The administrative status of OSPF. When OSPF is enbled on at least
514 one interface return 1. */
515 static int ospf_admin_stat(struct ospf
*ospf
)
517 struct listnode
*node
;
518 struct ospf_interface
*oi
;
523 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
524 if (oi
&& oi
->address
)
530 static uint8_t *ospfGeneralGroup(struct variable
*v
, oid
*name
, size_t *length
,
531 int exact
, size_t *var_len
,
532 WriteMethod
**write_method
)
536 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
538 /* Check whether the instance identifier is valid */
539 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
543 /* Return the current value of the variable */
545 case OSPFROUTERID
: /* 1 */
546 /* Router-ID of this OSPF instance. */
548 return SNMP_IPADDRESS(ospf
->router_id
);
550 return SNMP_IPADDRESS(ospf_empty_addr
);
551 case OSPFADMINSTAT
: /* 2 */
552 /* The administrative status of OSPF in the router. */
553 if (ospf_admin_stat(ospf
))
554 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
556 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
557 case OSPFVERSIONNUMBER
: /* 3 */
558 /* OSPF version 2. */
559 return SNMP_INTEGER(OSPF_VERSION
);
560 case OSPFAREABDRRTRSTATUS
: /* 4 */
561 /* Area Border router status. */
562 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ABR
))
563 return SNMP_INTEGER(SNMP_TRUE
);
565 return SNMP_INTEGER(SNMP_FALSE
);
566 case OSPFASBDRRTRSTATUS
: /* 5 */
567 /* AS Border router status. */
568 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ASBR
))
569 return SNMP_INTEGER(SNMP_TRUE
);
571 return SNMP_INTEGER(SNMP_FALSE
);
572 case OSPFEXTERNLSACOUNT
: /* 6 */
573 /* External LSA counts. */
575 return SNMP_INTEGER(ospf_lsdb_count_all(ospf
->lsdb
));
577 return SNMP_INTEGER(0);
578 case OSPFEXTERNLSACKSUMSUM
: /* 7 */
579 /* External LSA checksum. */
580 return SNMP_INTEGER(0);
581 case OSPFTOSSUPPORT
: /* 8 */
582 /* TOS is not supported. */
583 return SNMP_INTEGER(SNMP_FALSE
);
584 case OSPFORIGINATENEWLSAS
: /* 9 */
585 /* The number of new link-state advertisements. */
587 return SNMP_INTEGER(ospf
->lsa_originate_count
);
589 return SNMP_INTEGER(0);
590 case OSPFRXNEWLSAS
: /* 10 */
591 /* The number of link-state advertisements received determined
592 to be new instantiations. */
594 return SNMP_INTEGER(ospf
->rx_lsa_count
);
596 return SNMP_INTEGER(0);
597 case OSPFEXTLSDBLIMIT
: /* 11 */
598 /* There is no limit for the number of non-default
600 return SNMP_INTEGER(-1);
601 case OSPFMULTICASTEXTENSIONS
: /* 12 */
602 /* Multicast Extensions to OSPF is not supported. */
603 return SNMP_INTEGER(0);
604 case OSPFEXITOVERFLOWINTERVAL
: /* 13 */
605 /* Overflow is not supported. */
606 return SNMP_INTEGER(0);
607 case OSPFDEMANDEXTENSIONS
: /* 14 */
608 /* Demand routing is not supported. */
609 return SNMP_INTEGER(SNMP_FALSE
);
616 static struct ospf_area
*
617 ospf_area_lookup_next(struct ospf
*ospf
, struct in_addr
*area_id
, int first
)
619 struct ospf_area
*area
;
620 struct listnode
*node
;
626 node
= listhead(ospf
->areas
);
628 area
= listgetdata(node
);
629 *area_id
= area
->area_id
;
634 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
635 if (ntohl(area
->area_id
.s_addr
) > ntohl(area_id
->s_addr
)) {
636 *area_id
= area
->area_id
;
643 static struct ospf_area
*ospfAreaLookup(struct variable
*v
, oid name
[],
644 size_t *length
, struct in_addr
*addr
,
648 struct ospf_area
*area
;
651 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
656 /* Length is insufficient to lookup OSPF area. */
657 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
660 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
662 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
666 len
= *length
- v
->namelen
;
670 oid2in_addr(name
+ v
->namelen
, len
, addr
);
672 area
= ospf_area_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
677 oid_copy_addr(name
+ v
->namelen
, addr
, sizeof(struct in_addr
));
678 *length
= sizeof(struct in_addr
) + v
->namelen
;
685 static uint8_t *ospfAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
686 int exact
, size_t *var_len
,
687 WriteMethod
**write_method
)
689 struct ospf_area
*area
;
692 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
696 memset(&addr
, 0, sizeof(struct in_addr
));
698 area
= ospfAreaLookup(v
, name
, length
, &addr
, exact
);
702 /* Return the current value of the variable */
704 case OSPFAREAID
: /* 1 */
705 return SNMP_IPADDRESS(area
->area_id
);
706 case OSPFAUTHTYPE
: /* 2 */
707 return SNMP_INTEGER(area
->auth_type
);
708 case OSPFIMPORTASEXTERN
: /* 3 */
709 return SNMP_INTEGER(area
->external_routing
+ 1);
710 case OSPFSPFRUNS
: /* 4 */
711 return SNMP_INTEGER(area
->spf_calculation
);
712 case OSPFAREABDRRTRCOUNT
: /* 5 */
713 return SNMP_INTEGER(area
->abr_count
);
714 case OSPFASBDRRTRCOUNT
: /* 6 */
715 return SNMP_INTEGER(area
->asbr_count
);
716 case OSPFAREALSACOUNT
: /* 7 */
717 return SNMP_INTEGER(area
->lsdb
->total
);
718 case OSPFAREALSACKSUMSUM
: /* 8 */
719 return SNMP_INTEGER(0);
720 case OSPFAREASUMMARY
: /* 9 */
721 #define OSPF_noAreaSummary 1
722 #define OSPF_sendAreaSummary 2
723 if (area
->no_summary
)
724 return SNMP_INTEGER(OSPF_noAreaSummary
);
726 return SNMP_INTEGER(OSPF_sendAreaSummary
);
727 case OSPFAREASTATUS
: /* 10 */
728 return SNMP_INTEGER(SNMP_VALID
);
735 static struct ospf_area
*ospf_stub_area_lookup_next(struct in_addr
*area_id
,
738 struct ospf_area
*area
;
739 struct listnode
*node
;
742 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
746 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
747 if (area
->external_routing
== OSPF_AREA_STUB
) {
749 *area_id
= area
->area_id
;
751 } else if (ntohl(area
->area_id
.s_addr
)
752 > ntohl(area_id
->s_addr
)) {
753 *area_id
= area
->area_id
;
761 static struct ospf_area
*ospfStubAreaLookup(struct variable
*v
, oid name
[],
763 struct in_addr
*addr
, int exact
)
766 struct ospf_area
*area
;
769 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
775 /* ospfStubAreaID + ospfStubTOS. */
776 if (*length
!= v
->namelen
+ sizeof(struct in_addr
) + 1)
779 /* Check ospfStubTOS is zero. */
780 if (name
[*length
- 1] != 0)
783 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
785 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
787 if (area
&& area
->external_routing
== OSPF_AREA_STUB
)
792 len
= *length
- v
->namelen
;
796 oid2in_addr(name
+ v
->namelen
, len
, addr
);
798 area
= ospf_stub_area_lookup_next(addr
, len
== 0 ? 1 : 0);
803 oid_copy_addr(name
+ v
->namelen
, addr
, sizeof(struct in_addr
));
805 name
[v
->namelen
+ sizeof(struct in_addr
)] = 0;
806 *length
= v
->namelen
+ sizeof(struct in_addr
) + 1;
813 static uint8_t *ospfStubAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
814 int exact
, size_t *var_len
,
815 WriteMethod
**write_method
)
817 struct ospf_area
*area
;
820 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
824 memset(&addr
, 0, sizeof(struct in_addr
));
826 area
= ospfStubAreaLookup(v
, name
, length
, &addr
, exact
);
830 /* Return the current value of the variable */
832 case OSPFSTUBAREAID
: /* 1 */
833 /* OSPF stub area id. */
834 return SNMP_IPADDRESS(area
->area_id
);
835 case OSPFSTUBTOS
: /* 2 */
836 /* TOS value is not supported. */
837 return SNMP_INTEGER(0);
838 case OSPFSTUBMETRIC
: /* 3 */
839 /* Default cost to stub area. */
840 return SNMP_INTEGER(area
->default_cost
);
841 case OSPFSTUBSTATUS
: /* 4 */
842 /* Status of the stub area. */
843 return SNMP_INTEGER(SNMP_VALID
);
844 case OSPFSTUBMETRICTYPE
: /* 5 */
845 /* OSPF Metric type. */
846 #define OSPF_ospfMetric 1
847 #define OSPF_comparableCost 2
848 #define OSPF_nonComparable 3
849 return SNMP_INTEGER(OSPF_ospfMetric
);
856 static struct ospf_lsa
*lsdb_lookup_next(struct ospf_area
*area
, uint8_t *type
,
857 int type_next
, struct in_addr
*ls_id
,
859 struct in_addr
*router_id
,
862 struct ospf_lsa
*lsa
;
870 /* Sanity check, if LSA type unknwon
871 merley skip any LSA */
872 if ((i
< OSPF_MIN_LSA
) || (i
>= OSPF_MAX_LSA
)) {
873 zlog_debug("Strange request with LSA type %d", i
);
877 for (; i
< OSPF_MAX_LSA
; i
++) {
880 lsa
= ospf_lsdb_lookup_by_id_next(area
->lsdb
, *type
, *ls_id
,
881 *router_id
, ls_id_next
);
890 static struct ospf_lsa
*ospfLsdbLookup(struct variable
*v
, oid
*name
,
891 size_t *length
, struct in_addr
*area_id
,
892 uint8_t *type
, struct in_addr
*ls_id
,
893 struct in_addr
*router_id
, int exact
)
896 struct ospf_area
*area
;
897 struct ospf_lsa
*lsa
;
905 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
907 #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
910 /* Area ID + Type + LS ID + Router ID. */
911 if (*length
- v
->namelen
!= OSPF_LSDB_ENTRY_OFFSET
)
914 /* Set OID offset for Area ID. */
915 offset
= name
+ v
->namelen
;
917 /* Lookup area first. */
918 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
919 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
922 offset
+= IN_ADDR_SIZE
;
929 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
930 offset
+= IN_ADDR_SIZE
;
933 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
936 return ospf_lsdb_lookup_by_id(area
->lsdb
, *type
, *ls_id
,
939 /* Get variable length. */
940 offset
= name
+ v
->namelen
;
941 offsetlen
= *length
- v
->namelen
;
944 if (len
> (int)IN_ADDR_SIZE
)
947 oid2in_addr(offset
, len
, area_id
);
949 /* First we search area. */
950 if (len
== IN_ADDR_SIZE
)
951 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
953 area
= ospf_area_lookup_next(ospf
, area_id
, 1);
959 /* Next we lookup type. */
980 if (len
> (int)IN_ADDR_SIZE
)
983 oid2in_addr(offset
, len
, ls_id
);
987 offset
+= IN_ADDR_SIZE
;
988 offsetlen
-= IN_ADDR_SIZE
;
995 if (len
> (int)IN_ADDR_SIZE
)
998 oid2in_addr(offset
, len
, router_id
);
1001 lsa
= lsdb_lookup_next(area
, type
, type_next
, ls_id
,
1002 ls_id_next
, router_id
,
1006 /* Fill in length. */
1007 *length
= v
->namelen
+ OSPF_LSDB_ENTRY_OFFSET
;
1009 /* Fill in value. */
1010 offset
= name
+ v
->namelen
;
1011 oid_copy_addr(offset
, area_id
, IN_ADDR_SIZE
);
1012 offset
+= IN_ADDR_SIZE
;
1013 *offset
= lsa
->data
->type
;
1015 oid_copy_addr(offset
, &lsa
->data
->id
,
1017 offset
+= IN_ADDR_SIZE
;
1018 oid_copy_addr(offset
, &lsa
->data
->adv_router
,
1023 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1029 static uint8_t *ospfLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
1030 int exact
, size_t *var_len
,
1031 WriteMethod
**write_method
)
1033 struct ospf_lsa
*lsa
;
1034 struct lsa_header
*lsah
;
1035 struct in_addr area_id
;
1037 struct in_addr ls_id
;
1038 struct in_addr router_id
;
1041 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1045 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1046 ospfLsdbLsid, ospfLsdbRouterId } */
1048 memset(&area_id
, 0, sizeof(struct in_addr
));
1050 memset(&ls_id
, 0, sizeof(struct in_addr
));
1051 memset(&router_id
, 0, sizeof(struct in_addr
));
1053 /* Check OSPF instance. */
1054 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1058 lsa
= ospfLsdbLookup(v
, name
, length
, &area_id
, &type
, &ls_id
,
1065 /* Return the current value of the variable */
1067 case OSPFLSDBAREAID
: /* 1 */
1068 return SNMP_IPADDRESS(lsa
->area
->area_id
);
1069 case OSPFLSDBTYPE
: /* 2 */
1070 return SNMP_INTEGER(lsah
->type
);
1071 case OSPFLSDBLSID
: /* 3 */
1072 return SNMP_IPADDRESS(lsah
->id
);
1073 case OSPFLSDBROUTERID
: /* 4 */
1074 return SNMP_IPADDRESS(lsah
->adv_router
);
1075 case OSPFLSDBSEQUENCE
: /* 5 */
1076 return SNMP_INTEGER(lsah
->ls_seqnum
);
1077 case OSPFLSDBAGE
: /* 6 */
1078 return SNMP_INTEGER(lsah
->ls_age
);
1079 case OSPFLSDBCHECKSUM
: /* 7 */
1080 return SNMP_INTEGER(lsah
->checksum
);
1081 case OSPFLSDBADVERTISEMENT
: /* 8 */
1082 *var_len
= ntohs(lsah
->length
);
1083 return (uint8_t *)lsah
;
1090 static struct ospf_area_range
*ospfAreaRangeLookup(struct variable
*v
,
1091 oid
*name
, size_t *length
,
1092 struct in_addr
*area_id
,
1093 struct in_addr
*range_net
,
1100 struct ospf_area
*area
;
1101 struct ospf_area_range
*range
;
1102 struct prefix_ipv4 p
;
1104 p
.prefixlen
= IPV4_MAX_BITLEN
;
1106 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1109 /* Area ID + Range Network. */
1110 if (v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
!= *length
)
1113 /* Set OID offset for Area ID. */
1114 offset
= name
+ v
->namelen
;
1116 /* Lookup area first. */
1117 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
1119 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1123 offset
+= IN_ADDR_SIZE
;
1125 /* Lookup area range. */
1126 oid2in_addr(offset
, IN_ADDR_SIZE
, range_net
);
1127 p
.prefix
= *range_net
;
1129 return ospf_area_range_lookup(area
, &p
);
1131 /* Set OID offset for Area ID. */
1132 offset
= name
+ v
->namelen
;
1133 offsetlen
= *length
- v
->namelen
;
1136 if (len
> (int)IN_ADDR_SIZE
)
1139 oid2in_addr(offset
, len
, area_id
);
1141 /* First we search area. */
1142 if (len
== IN_ADDR_SIZE
)
1143 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1145 area
= ospf_area_lookup_next(ospf
, area_id
,
1152 offset
+= IN_ADDR_SIZE
;
1153 offsetlen
-= IN_ADDR_SIZE
;
1158 if (len
> (int)IN_ADDR_SIZE
)
1161 oid2in_addr(offset
, len
, range_net
);
1163 range
= ospf_area_range_lookup_next(area
, range_net
,
1167 /* Fill in length. */
1168 *length
= v
->namelen
+ IN_ADDR_SIZE
1171 /* Fill in value. */
1172 offset
= name
+ v
->namelen
;
1173 oid_copy_addr(offset
, area_id
, IN_ADDR_SIZE
);
1174 offset
+= IN_ADDR_SIZE
;
1175 oid_copy_addr(offset
, range_net
, IN_ADDR_SIZE
);
1179 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1185 static uint8_t *ospfAreaRangeEntry(struct variable
*v
, oid
*name
,
1186 size_t *length
, int exact
, size_t *var_len
,
1187 WriteMethod
**write_method
)
1189 struct ospf_area_range
*range
;
1190 struct in_addr area_id
;
1191 struct in_addr range_net
;
1192 struct in_addr mask
;
1195 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1199 /* Check OSPF instance. */
1200 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1204 memset(&area_id
, 0, IN_ADDR_SIZE
);
1205 memset(&range_net
, 0, IN_ADDR_SIZE
);
1207 range
= ospfAreaRangeLookup(v
, name
, length
, &area_id
, &range_net
,
1212 /* Convert prefixlen to network mask format. */
1213 masklen2ip(range
->subst_masklen
, &mask
);
1215 /* Return the current value of the variable */
1217 case OSPFAREARANGEAREAID
: /* 1 */
1218 return SNMP_IPADDRESS(area_id
);
1219 case OSPFAREARANGENET
: /* 2 */
1220 return SNMP_IPADDRESS(range_net
);
1221 case OSPFAREARANGEMASK
: /* 3 */
1222 return SNMP_IPADDRESS(mask
);
1223 case OSPFAREARANGESTATUS
: /* 4 */
1224 return SNMP_INTEGER(SNMP_VALID
);
1225 case OSPFAREARANGEEFFECT
: /* 5 */
1226 #define OSPF_advertiseMatching 1
1227 #define OSPF_doNotAdvertiseMatching 2
1228 return SNMP_INTEGER(OSPF_advertiseMatching
);
1235 static struct ospf_nbr_nbma
*ospfHostLookup(struct variable
*v
, oid
*name
,
1237 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
);
1262 len
= *length
- v
->namelen
;
1266 oid2in_addr(name
+ v
->namelen
, len
, addr
);
1269 ospf_nbr_nbma_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
1271 if (nbr_nbma
== NULL
)
1274 oid_copy_addr(name
+ v
->namelen
, addr
, IN_ADDR_SIZE
);
1277 name
[v
->namelen
+ IN_ADDR_SIZE
] = 0;
1279 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1286 static uint8_t *ospfHostEntry(struct variable
*v
, oid
*name
, size_t *length
,
1287 int exact
, size_t *var_len
,
1288 WriteMethod
**write_method
)
1290 struct ospf_nbr_nbma
*nbr_nbma
;
1291 struct ospf_interface
*oi
;
1292 struct in_addr addr
;
1295 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1299 /* Check OSPF instance. */
1300 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1304 memset(&addr
, 0, sizeof(struct in_addr
));
1306 nbr_nbma
= ospfHostLookup(v
, name
, length
, &addr
, exact
);
1307 if (nbr_nbma
== NULL
)
1312 /* Return the current value of the variable */
1314 case OSPFHOSTIPADDRESS
: /* 1 */
1315 return SNMP_IPADDRESS(nbr_nbma
->addr
);
1316 case OSPFHOSTTOS
: /* 2 */
1317 return SNMP_INTEGER(0);
1318 case OSPFHOSTMETRIC
: /* 3 */
1320 return SNMP_INTEGER(oi
->output_cost
);
1322 return SNMP_INTEGER(1);
1323 case OSPFHOSTSTATUS
: /* 4 */
1324 return SNMP_INTEGER(SNMP_VALID
);
1325 case OSPFHOSTAREAID
: /* 5 */
1327 return SNMP_IPADDRESS(oi
->area
->area_id
);
1329 return SNMP_IPADDRESS(ospf_empty_addr
);
1336 static struct list
*ospf_snmp_iflist
;
1338 struct ospf_snmp_if
{
1339 struct in_addr addr
;
1341 struct interface
*ifp
;
1344 static struct ospf_snmp_if
*ospf_snmp_if_new(void)
1346 return XCALLOC(MTYPE_TMP
, sizeof(struct ospf_snmp_if
));
1349 static void ospf_snmp_if_free(struct ospf_snmp_if
*osif
)
1351 XFREE(MTYPE_TMP
, osif
);
1354 static int ospf_snmp_if_delete(struct interface
*ifp
)
1356 struct listnode
*node
, *nnode
;
1357 struct ospf_snmp_if
*osif
;
1359 for (ALL_LIST_ELEMENTS(ospf_snmp_iflist
, node
, nnode
, osif
)) {
1360 if (osif
->ifp
== ifp
) {
1361 list_delete_node(ospf_snmp_iflist
, node
);
1362 ospf_snmp_if_free(osif
);
1369 static int ospf_snmp_if_update(struct interface
*ifp
)
1371 struct listnode
*node
;
1372 struct listnode
*pn
;
1373 struct connected
*ifc
;
1375 struct ospf_snmp_if
*osif
;
1376 struct in_addr
*addr
;
1379 ospf_snmp_if_delete(ifp
);
1385 /* Lookup first IPv4 address entry. */
1386 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1387 p
= CONNECTED_ID(ifc
);
1389 if (p
->family
== AF_INET
) {
1390 addr
= &p
->u
.prefix4
;
1395 ifindex
= ifp
->ifindex
;
1397 /* Add interface to the list. */
1399 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1401 /* Usual interfaces --> Sort them based on interface
1403 if (ntohl(osif
->addr
.s_addr
) > ntohl(addr
->s_addr
))
1406 /* Unnumbered interfaces --> Sort them based on
1407 * interface indexes */
1408 if (osif
->addr
.s_addr
!= INADDR_ANY
1409 || osif
->ifindex
> ifindex
)
1415 osif
= ospf_snmp_if_new();
1416 if (addr
) /* Usual interface */
1420 /* This field is used for storing ospfAddressLessIf OID value,
1421 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1422 * usual interface */
1424 } else /* Unnumbered interface */
1425 osif
->ifindex
= ifindex
;
1428 listnode_add_after(ospf_snmp_iflist
, pn
, osif
);
1432 static int ospf_snmp_is_if_have_addr(struct interface
*ifp
)
1434 struct listnode
*nn
;
1435 struct connected
*ifc
;
1437 /* Is this interface having any connected IPv4 address ? */
1438 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, nn
, ifc
)) {
1439 if (CONNECTED_PREFIX(ifc
)->family
== AF_INET
)
1446 static struct ospf_interface
*ospf_snmp_if_lookup(struct in_addr
*ifaddr
,
1449 struct listnode
*node
;
1450 struct ospf_snmp_if
*osif
;
1451 struct ospf_interface
*oi
= NULL
;
1452 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1454 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1455 if (ifaddr
->s_addr
) {
1456 if (IPV4_ADDR_SAME(&osif
->addr
, ifaddr
))
1457 oi
= ospf_if_lookup_by_local_addr(
1458 ospf
, osif
->ifp
, *ifaddr
);
1460 if (osif
->ifindex
== *ifindex
)
1461 oi
= ospf_if_lookup_by_local_addr(
1462 ospf
, osif
->ifp
, *ifaddr
);
1468 static struct ospf_interface
*ospf_snmp_if_lookup_next(struct in_addr
*ifaddr
,
1471 ifindex_t ifindex_next
)
1473 struct ospf_snmp_if
*osif
;
1474 struct listnode
*nn
;
1475 struct ospf
*ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1476 struct ospf_interface
*oi
= NULL
;
1481 /* No instance is specified --> Return the first OSPF interface */
1483 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1484 osif
= listgetdata(nn
);
1485 *ifaddr
= osif
->addr
;
1486 *ifindex
= osif
->ifindex
;
1487 /* Because no instance is specified, we don't care about
1489 * interface (usual or unnumbered), just returning the
1492 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1500 /* An instance is specified --> Return the next OSPF interface */
1501 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1502 /* Usual interface */
1503 if (ifaddr
->s_addr
) {
1504 /* The interface must have valid AF_INET connected
1506 /* it must have lager IPv4 address value than the lookup
1508 if ((ospf_snmp_is_if_have_addr(osif
->ifp
))
1509 && (ntohl(osif
->addr
.s_addr
)
1510 > ntohl(ifaddr
->s_addr
))) {
1511 *ifaddr
= osif
->addr
;
1512 *ifindex
= osif
->ifindex
;
1514 /* and it must be an OSPF interface */
1515 oi
= ospf_if_lookup_by_local_addr(
1516 ospf
, osif
->ifp
, *ifaddr
);
1521 /* Unnumbered interface */
1523 /* The interface must NOT have valid AF_INET connected
1525 /* it must have lager interface index than the lookup
1527 if ((!ospf_snmp_is_if_have_addr(osif
->ifp
))
1528 && (osif
->ifindex
> *ifindex
)) {
1529 *ifaddr
= osif
->addr
;
1530 *ifindex
= osif
->ifindex
;
1532 /* and it must be an OSPF interface */
1533 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1542 static int ospf_snmp_iftype(struct interface
*ifp
)
1544 #define ospf_snmp_iftype_broadcast 1
1545 #define ospf_snmp_iftype_nbma 2
1546 #define ospf_snmp_iftype_pointToPoint 3
1547 #define ospf_snmp_iftype_pointToMultipoint 5
1548 if (if_is_broadcast(ifp
))
1549 return ospf_snmp_iftype_broadcast
;
1550 if (if_is_pointopoint(ifp
))
1551 return ospf_snmp_iftype_pointToPoint
;
1552 return ospf_snmp_iftype_broadcast
;
1555 static struct ospf_interface
*ospfIfLookup(struct variable
*v
, oid
*name
,
1557 struct in_addr
*ifaddr
,
1558 ifindex_t
*ifindex
, int exact
)
1561 int ifaddr_next
= 0;
1562 ifindex_t ifindex_next
= 0;
1563 struct ospf_interface
*oi
;
1567 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1570 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1571 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1573 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1575 len
= *length
- v
->namelen
;
1576 if (len
>= IN_ADDR_SIZE
)
1581 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1583 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1590 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1592 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1595 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1596 offset
= name
+ v
->namelen
;
1597 oid_copy_addr(offset
, ifaddr
, IN_ADDR_SIZE
);
1598 offset
+= IN_ADDR_SIZE
;
1606 static uint8_t *ospfIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1607 int exact
, size_t *var_len
,
1608 WriteMethod
**write_method
)
1611 struct in_addr ifaddr
;
1612 struct ospf_interface
*oi
;
1615 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1620 memset(&ifaddr
, 0, sizeof(struct in_addr
));
1622 /* Check OSPF instance. */
1623 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1627 oi
= ospfIfLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1631 /* Return the current value of the variable */
1633 case OSPFIFIPADDRESS
: /* 1 */
1634 return SNMP_IPADDRESS(ifaddr
);
1635 case OSPFADDRESSLESSIF
: /* 2 */
1636 return SNMP_INTEGER(ifindex
);
1637 case OSPFIFAREAID
: /* 3 */
1639 return SNMP_IPADDRESS(oi
->area
->area_id
);
1641 return SNMP_IPADDRESS(ospf_empty_addr
);
1642 case OSPFIFTYPE
: /* 4 */
1643 return SNMP_INTEGER(ospf_snmp_iftype(oi
->ifp
));
1644 case OSPFIFADMINSTAT
: /* 5 */
1646 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1648 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1649 case OSPFIFRTRPRIORITY
: /* 6 */
1650 return SNMP_INTEGER(PRIORITY(oi
));
1651 case OSPFIFTRANSITDELAY
: /* 7 */
1652 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1653 case OSPFIFRETRANSINTERVAL
: /* 8 */
1654 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1655 case OSPFIFHELLOINTERVAL
: /* 9 */
1656 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1657 case OSPFIFRTRDEADINTERVAL
: /* 10 */
1658 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1659 case OSPFIFPOLLINTERVAL
: /* 11 */
1660 return SNMP_INTEGER(OSPF_POLL_INTERVAL_DEFAULT
);
1661 case OSPFIFSTATE
: /* 12 */
1662 return SNMP_INTEGER(ISM_SNMP(oi
->state
));
1663 case OSPFIFDESIGNATEDROUTER
: /* 13 */
1664 return SNMP_IPADDRESS(DR(oi
));
1665 case OSPFIFBACKUPDESIGNATEDROUTER
: /* 14 */
1666 return SNMP_IPADDRESS(BDR(oi
));
1667 case OSPFIFEVENTS
: /* 15 */
1668 return SNMP_INTEGER(oi
->state_change
);
1669 case OSPFIFAUTHKEY
: /* 16 */
1671 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1672 case OSPFIFSTATUS
: /* 17 */
1673 return SNMP_INTEGER(SNMP_VALID
);
1674 case OSPFIFMULTICASTFORWARDING
: /* 18 */
1675 #define ospf_snmp_multiforward_blocked 1
1676 #define ospf_snmp_multiforward_multicast 2
1677 #define ospf_snmp_multiforward_unicast 3
1678 return SNMP_INTEGER(ospf_snmp_multiforward_blocked
);
1679 case OSPFIFDEMAND
: /* 19 */
1680 return SNMP_INTEGER(SNMP_FALSE
);
1681 case OSPFIFAUTHTYPE
: /* 20 */
1683 return SNMP_INTEGER(oi
->area
->auth_type
);
1685 return SNMP_INTEGER(0);
1692 #define OSPF_SNMP_METRIC_VALUE 1
1694 static struct ospf_interface
*ospfIfMetricLookup(struct variable
*v
, oid
*name
,
1696 struct in_addr
*ifaddr
,
1697 ifindex_t
*ifindex
, int exact
)
1700 int ifaddr_next
= 0;
1701 ifindex_t ifindex_next
= 0;
1702 struct ospf_interface
*oi
;
1707 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1)
1710 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1711 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1712 metric
= name
[v
->namelen
+ IN_ADDR_SIZE
+ 1];
1714 if (metric
!= OSPF_SNMP_METRIC_VALUE
)
1717 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1719 len
= *length
- v
->namelen
;
1720 if (len
>= IN_ADDR_SIZE
)
1725 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1727 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1734 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1736 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1739 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1;
1740 offset
= name
+ v
->namelen
;
1741 oid_copy_addr(offset
, ifaddr
, IN_ADDR_SIZE
);
1742 offset
+= IN_ADDR_SIZE
;
1745 *offset
= OSPF_SNMP_METRIC_VALUE
;
1752 static uint8_t *ospfIfMetricEntry(struct variable
*v
, oid
*name
, size_t *length
,
1753 int exact
, size_t *var_len
,
1754 WriteMethod
**write_method
)
1756 /* Currently we support metric 1 only. */
1758 struct in_addr ifaddr
;
1759 struct ospf_interface
*oi
;
1762 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1767 memset(&ifaddr
, 0, sizeof(struct in_addr
));
1769 /* Check OSPF instance. */
1770 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1774 oi
= ospfIfMetricLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1778 /* Return the current value of the variable */
1780 case OSPFIFMETRICIPADDRESS
:
1781 return SNMP_IPADDRESS(ifaddr
);
1782 case OSPFIFMETRICADDRESSLESSIF
:
1783 return SNMP_INTEGER(ifindex
);
1784 case OSPFIFMETRICTOS
:
1785 return SNMP_INTEGER(0);
1786 case OSPFIFMETRICVALUE
:
1787 return SNMP_INTEGER(OSPF_SNMP_METRIC_VALUE
);
1788 case OSPFIFMETRICSTATUS
:
1789 return SNMP_INTEGER(1);
1796 static struct route_table
*ospf_snmp_vl_table
;
1798 static int ospf_snmp_vl_add(struct ospf_vl_data
*vl_data
)
1800 struct prefix_ls lp
;
1801 struct route_node
*rn
;
1803 memset(&lp
, 0, sizeof(struct prefix_ls
));
1806 lp
.id
= vl_data
->vl_area_id
;
1807 lp
.adv_router
= vl_data
->vl_peer
;
1809 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1811 route_unlock_node(rn
);
1817 static int ospf_snmp_vl_delete(struct ospf_vl_data
*vl_data
)
1819 struct prefix_ls lp
;
1820 struct route_node
*rn
;
1822 memset(&lp
, 0, sizeof(struct prefix_ls
));
1825 lp
.id
= vl_data
->vl_area_id
;
1826 lp
.adv_router
= vl_data
->vl_peer
;
1828 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1832 route_unlock_node(rn
);
1833 route_unlock_node(rn
);
1837 static struct ospf_vl_data
*ospf_snmp_vl_lookup(struct in_addr
*area_id
,
1838 struct in_addr
*neighbor
)
1840 struct prefix_ls lp
;
1841 struct route_node
*rn
;
1842 struct ospf_vl_data
*vl_data
;
1844 memset(&lp
, 0, sizeof(struct prefix_ls
));
1848 lp
.adv_router
= *neighbor
;
1850 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1853 route_unlock_node(rn
);
1859 static struct ospf_vl_data
*ospf_snmp_vl_lookup_next(struct in_addr
*area_id
,
1860 struct in_addr
*neighbor
,
1863 struct prefix_ls lp
;
1864 struct route_node
*rn
;
1865 struct ospf_vl_data
*vl_data
;
1867 memset(&lp
, 0, sizeof(struct prefix_ls
));
1871 lp
.adv_router
= *neighbor
;
1874 rn
= route_top(ospf_snmp_vl_table
);
1876 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1877 rn
= route_next(rn
);
1880 for (; rn
; rn
= route_next(rn
))
1884 if (rn
&& rn
->info
) {
1886 *area_id
= vl_data
->vl_area_id
;
1887 *neighbor
= vl_data
->vl_peer
;
1888 route_unlock_node(rn
);
1894 static struct ospf_vl_data
*
1895 ospfVirtIfLookup(struct variable
*v
, oid
*name
, size_t *length
,
1896 struct in_addr
*area_id
, struct in_addr
*neighbor
, int exact
)
1900 struct ospf_vl_data
*vl_data
;
1903 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
1906 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, area_id
);
1907 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, IN_ADDR_SIZE
,
1910 return ospf_snmp_vl_lookup(area_id
, neighbor
);
1914 len
= *length
- v
->namelen
;
1917 if (len
> IN_ADDR_SIZE
)
1919 oid2in_addr(name
+ v
->namelen
, len
, area_id
);
1921 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1922 if (len
> IN_ADDR_SIZE
)
1924 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, len
, neighbor
);
1926 vl_data
= ospf_snmp_vl_lookup_next(area_id
, neighbor
, first
);
1929 *length
= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
1930 oid_copy_addr(name
+ v
->namelen
, area_id
, IN_ADDR_SIZE
);
1931 oid_copy_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
,
1932 neighbor
, IN_ADDR_SIZE
);
1939 static uint8_t *ospfVirtIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1940 int exact
, size_t *var_len
,
1941 WriteMethod
**write_method
)
1943 struct ospf_vl_data
*vl_data
;
1944 struct ospf_interface
*oi
;
1945 struct in_addr area_id
;
1946 struct in_addr neighbor
;
1948 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1952 memset(&area_id
, 0, sizeof(struct in_addr
));
1953 memset(&neighbor
, 0, sizeof(struct in_addr
));
1955 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
1958 oi
= vl_data
->vl_oi
;
1962 /* Return the current value of the variable */
1964 case OSPFVIRTIFAREAID
:
1965 return SNMP_IPADDRESS(area_id
);
1966 case OSPFVIRTIFNEIGHBOR
:
1967 return SNMP_IPADDRESS(neighbor
);
1968 case OSPFVIRTIFTRANSITDELAY
:
1969 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1970 case OSPFVIRTIFRETRANSINTERVAL
:
1971 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1972 case OSPFVIRTIFHELLOINTERVAL
:
1973 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1974 case OSPFVIRTIFRTRDEADINTERVAL
:
1975 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1976 case OSPFVIRTIFSTATE
:
1977 return SNMP_INTEGER(oi
->state
);
1978 case OSPFVIRTIFEVENTS
:
1979 return SNMP_INTEGER(oi
->state_change
);
1980 case OSPFVIRTIFAUTHKEY
:
1982 return (uint8_t *)OSPF_IF_PARAM(oi
, auth_simple
);
1983 case OSPFVIRTIFSTATUS
:
1984 return SNMP_INTEGER(SNMP_VALID
);
1985 case OSPFVIRTIFAUTHTYPE
:
1987 return SNMP_INTEGER(oi
->area
->auth_type
);
1989 return SNMP_INTEGER(0);
1996 static struct ospf_neighbor
*ospf_snmp_nbr_lookup(struct ospf
*ospf
,
1997 struct in_addr
*nbr_addr
,
2000 struct listnode
*node
, *nnode
;
2001 struct ospf_interface
*oi
;
2002 struct ospf_neighbor
*nbr
;
2003 struct route_node
*rn
;
2005 for (ALL_LIST_ELEMENTS(ospf
->oiflist
, node
, nnode
, oi
)) {
2006 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2007 if ((nbr
= rn
->info
) != NULL
2008 && nbr
!= oi
->nbr_self
2009 /* If EXACT match is needed, provide ALL entry found
2010 && nbr->state != NSM_Down
2012 && nbr
->src
.s_addr
!= INADDR_ANY
) {
2013 if (IPV4_ADDR_SAME(&nbr
->src
, nbr_addr
)) {
2014 route_unlock_node(rn
);
2022 static struct ospf_neighbor
*ospf_snmp_nbr_lookup_next(struct in_addr
*nbr_addr
,
2026 struct listnode
*nn
;
2027 struct ospf_interface
*oi
;
2028 struct ospf_neighbor
*nbr
;
2029 struct route_node
*rn
;
2030 struct ospf_neighbor
*min
= NULL
;
2033 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2035 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, nn
, oi
)) {
2036 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2037 if ((nbr
= rn
->info
) != NULL
&& nbr
!= oi
->nbr_self
2038 && nbr
->state
!= NSM_Down
2039 && nbr
->src
.s_addr
!= INADDR_ANY
) {
2043 else if (ntohl(nbr
->src
.s_addr
)
2044 < ntohl(min
->src
.s_addr
))
2046 } else if (ntohl(nbr
->src
.s_addr
)
2047 > ntohl(nbr_addr
->s_addr
)) {
2050 else if (ntohl(nbr
->src
.s_addr
)
2051 < ntohl(min
->src
.s_addr
))
2057 *nbr_addr
= min
->src
;
2064 static struct ospf_neighbor
*ospfNbrLookup(struct variable
*v
, oid
*name
,
2066 struct in_addr
*nbr_addr
,
2067 ifindex_t
*ifindex
, int exact
)
2071 struct ospf_neighbor
*nbr
;
2074 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2080 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
2083 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, nbr_addr
);
2084 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2086 return ospf_snmp_nbr_lookup(ospf
, nbr_addr
, ifindex
);
2089 len
= *length
- v
->namelen
;
2094 if (len
> IN_ADDR_SIZE
)
2097 oid2in_addr(name
+ v
->namelen
, len
, nbr_addr
);
2099 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
2101 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2103 nbr
= ospf_snmp_nbr_lookup_next(nbr_addr
, ifindex
, first
);
2106 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
2107 oid_copy_addr(name
+ v
->namelen
, nbr_addr
,
2109 name
[v
->namelen
+ IN_ADDR_SIZE
] = *ifindex
;
2116 /* map internal quagga neighbor states to official MIB values:
2118 ospfNbrState OBJECT-TYPE
2130 static int32_t ospf_snmp_neighbor_state(uint8_t nst
)
2148 return 1; /* down */
2152 static uint8_t *ospfNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2153 int exact
, size_t *var_len
,
2154 WriteMethod
**write_method
)
2156 struct in_addr nbr_addr
;
2158 struct ospf_neighbor
*nbr
;
2159 struct ospf_interface
*oi
;
2161 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2165 memset(&nbr_addr
, 0, sizeof(struct in_addr
));
2168 nbr
= ospfNbrLookup(v
, name
, length
, &nbr_addr
, &ifindex
, exact
);
2173 /* Return the current value of the variable */
2176 return SNMP_IPADDRESS(nbr_addr
);
2177 case OSPFNBRADDRESSLESSINDEX
:
2178 return SNMP_INTEGER(ifindex
);
2180 return SNMP_IPADDRESS(nbr
->router_id
);
2181 case OSPFNBROPTIONS
:
2182 return SNMP_INTEGER(oi
->nbr_self
->options
);
2183 case OSPFNBRPRIORITY
:
2184 return SNMP_INTEGER(nbr
->priority
);
2186 return SNMP_INTEGER(ospf_snmp_neighbor_state(nbr
->state
));
2188 return SNMP_INTEGER(nbr
->state_change
);
2189 case OSPFNBRLSRETRANSQLEN
:
2190 return SNMP_INTEGER(ospf_ls_retransmit_count(nbr
));
2191 case OSPFNBMANBRSTATUS
:
2192 return SNMP_INTEGER(SNMP_VALID
);
2193 case OSPFNBMANBRPERMANENCE
:
2194 return SNMP_INTEGER(2);
2195 case OSPFNBRHELLOSUPPRESSED
:
2196 return SNMP_INTEGER(SNMP_FALSE
);
2203 static uint8_t *ospfVirtNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2204 int exact
, size_t *var_len
,
2205 WriteMethod
**write_method
)
2207 struct ospf_vl_data
*vl_data
;
2208 struct in_addr area_id
;
2209 struct in_addr neighbor
;
2212 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2216 memset(&area_id
, 0, sizeof(struct in_addr
));
2217 memset(&neighbor
, 0, sizeof(struct in_addr
));
2219 /* Check OSPF instance. */
2220 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2224 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
2228 /* Return the current value of the variable */
2230 case OSPFVIRTNBRAREA
:
2231 return (uint8_t *)NULL
;
2232 case OSPFVIRTNBRRTRID
:
2233 return (uint8_t *)NULL
;
2234 case OSPFVIRTNBRIPADDR
:
2235 return (uint8_t *)NULL
;
2236 case OSPFVIRTNBROPTIONS
:
2237 return (uint8_t *)NULL
;
2238 case OSPFVIRTNBRSTATE
:
2239 return (uint8_t *)NULL
;
2240 case OSPFVIRTNBREVENTS
:
2241 return (uint8_t *)NULL
;
2242 case OSPFVIRTNBRLSRETRANSQLEN
:
2243 return (uint8_t *)NULL
;
2244 case OSPFVIRTNBRHELLOSUPPRESSED
:
2245 return (uint8_t *)NULL
;
2252 static struct ospf_lsa
*ospfExtLsdbLookup(struct variable
*v
, oid
*name
,
2253 size_t *length
, uint8_t *type
,
2254 struct in_addr
*ls_id
,
2255 struct in_addr
*router_id
, int exact
)
2262 struct ospf_lsa
*lsa
;
2265 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2267 if (*length
!= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
2270 offset
= name
+ v
->namelen
;
2272 /* Make it sure given value match to type. */
2276 if (lsa_type
!= *type
)
2280 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
2281 offset
+= IN_ADDR_SIZE
;
2284 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
2286 return ospf_lsdb_lookup_by_id(ospf
->lsdb
, *type
, *ls_id
,
2289 /* Get variable length. */
2291 offset
= name
+ v
->namelen
;
2292 offsetlen
= *length
- v
->namelen
;
2294 /* LSA type value. */
2299 if (offsetlen
<= 0 || lsa_type
< OSPF_AS_EXTERNAL_LSA
)
2304 if (len
> IN_ADDR_SIZE
)
2307 oid2in_addr(offset
, len
, ls_id
);
2309 offset
+= IN_ADDR_SIZE
;
2310 offsetlen
-= IN_ADDR_SIZE
;
2314 if (len
> IN_ADDR_SIZE
)
2317 oid2in_addr(offset
, len
, router_id
);
2319 lsa
= ospf_lsdb_lookup_by_id_next(ospf
->lsdb
, *type
, *ls_id
,
2323 /* Fill in length. */
2324 *length
= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
2326 /* Fill in value. */
2327 offset
= name
+ v
->namelen
;
2329 *offset
= OSPF_AS_EXTERNAL_LSA
;
2331 oid_copy_addr(offset
, &lsa
->data
->id
, IN_ADDR_SIZE
);
2332 offset
+= IN_ADDR_SIZE
;
2333 oid_copy_addr(offset
, &lsa
->data
->adv_router
,
2342 static uint8_t *ospfExtLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
2343 int exact
, size_t *var_len
,
2344 WriteMethod
**write_method
)
2346 struct ospf_lsa
*lsa
;
2347 struct lsa_header
*lsah
;
2349 struct in_addr ls_id
;
2350 struct in_addr router_id
;
2353 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2357 type
= OSPF_AS_EXTERNAL_LSA
;
2358 memset(&ls_id
, 0, sizeof(struct in_addr
));
2359 memset(&router_id
, 0, sizeof(struct in_addr
));
2361 /* Check OSPF instance. */
2362 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
2366 lsa
= ospfExtLsdbLookup(v
, name
, length
, &type
, &ls_id
, &router_id
,
2373 /* Return the current value of the variable */
2375 case OSPFEXTLSDBTYPE
:
2376 return SNMP_INTEGER(OSPF_AS_EXTERNAL_LSA
);
2377 case OSPFEXTLSDBLSID
:
2378 return SNMP_IPADDRESS(lsah
->id
);
2379 case OSPFEXTLSDBROUTERID
:
2380 return SNMP_IPADDRESS(lsah
->adv_router
);
2381 case OSPFEXTLSDBSEQUENCE
:
2382 return SNMP_INTEGER(lsah
->ls_seqnum
);
2383 case OSPFEXTLSDBAGE
:
2384 return SNMP_INTEGER(lsah
->ls_age
);
2385 case OSPFEXTLSDBCHECKSUM
:
2386 return SNMP_INTEGER(lsah
->checksum
);
2387 case OSPFEXTLSDBADVERTISEMENT
:
2388 *var_len
= ntohs(lsah
->length
);
2389 return (uint8_t *)lsah
;
2396 static uint8_t *ospfAreaAggregateEntry(struct variable
*v
, oid
*name
,
2397 size_t *length
, int exact
,
2399 WriteMethod
**write_method
)
2401 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2405 /* Return the current value of the variable */
2407 case OSPFAREAAGGREGATEAREAID
:
2408 return (uint8_t *)NULL
;
2409 case OSPFAREAAGGREGATELSDBTYPE
:
2410 return (uint8_t *)NULL
;
2411 case OSPFAREAAGGREGATENET
:
2412 return (uint8_t *)NULL
;
2413 case OSPFAREAAGGREGATEMASK
:
2414 return (uint8_t *)NULL
;
2415 case OSPFAREAAGGREGATESTATUS
:
2416 return (uint8_t *)NULL
;
2417 case OSPFAREAAGGREGATEEFFECT
:
2418 return (uint8_t *)NULL
;
2426 #define IFSTATECHANGE 16
2427 #define VIRTIFSTATECHANGE 1
2428 #define NBRSTATECHANGE 2
2429 #define VIRTNBRSTATECHANGE 3
2431 static struct trap_object ospfNbrTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2432 {3, {10, 1, OSPFNBRIPADDR
}},
2433 {3, {10, 1, OSPFNBRRTRID
}},
2434 {3, {10, 1, OSPFNBRSTATE
}}};
2437 static struct trap_object ospfVirtNbrTrapList
[] = {
2439 {3, {11, 1, OSPFVIRTNBRAREA
}},
2440 {3, {11, 1, OSPFVIRTNBRRTRID
}},
2441 {3, {11, 1, OSPFVIRTNBRSTATE
}}};
2443 static struct trap_object ospfIfTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2444 {3, {7, 1, OSPFIFIPADDRESS
}},
2445 {3, {7, 1, OSPFADDRESSLESSIF
}},
2446 {3, {7, 1, OSPFIFSTATE
}}};
2448 static struct trap_object ospfVirtIfTrapList
[] = {
2449 {-2, {1, OSPFROUTERID
}},
2450 {3, {9, 1, OSPFVIRTIFAREAID
}},
2451 {3, {9, 1, OSPFVIRTIFNEIGHBOR
}},
2452 {3, {9, 1, OSPFVIRTIFSTATE
}}};
2454 static void ospfTrapNbrStateChange(struct ospf_neighbor
*on
)
2456 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2459 ospf_nbr_state_message(on
, msgbuf
, sizeof(msgbuf
));
2460 if (IS_DEBUG_OSPF_EVENT
)
2461 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2462 &on
->address
.u
.prefix4
, msgbuf
);
2464 oid_copy_addr(index
, &(on
->address
.u
.prefix4
), IN_ADDR_SIZE
);
2465 index
[IN_ADDR_SIZE
] = 0;
2467 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2468 array_size(ospf_trap_oid
), ospf_oid
,
2469 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2470 ospfNbrTrapList
, array_size(ospfNbrTrapList
), NBRSTATECHANGE
);
2473 static void ospfTrapVirtNbrStateChange(struct ospf_neighbor
*on
)
2475 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2477 zlog_info("ospfTrapVirtNbrStateChange trap sent");
2479 oid_copy_addr(index
, &(on
->address
.u
.prefix4
), IN_ADDR_SIZE
);
2480 index
[IN_ADDR_SIZE
] = 0;
2482 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2483 array_size(ospf_trap_oid
), ospf_oid
,
2484 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2485 ospfVirtNbrTrapList
, array_size(ospfVirtNbrTrapList
),
2486 VIRTNBRSTATECHANGE
);
2489 static int ospf_snmp_nsm_change(struct ospf_neighbor
*nbr
, int next_state
,
2492 /* Transition to/from state Full should be handled only by
2493 * DR when in Broadcast or Non-Brodcast Multi-Access networks
2495 if ((next_state
== NSM_Full
|| old_state
== NSM_Full
)
2496 && (nbr
->oi
->state
!= ISM_DR
)
2497 && (nbr
->oi
->type
== OSPF_IFTYPE_BROADCAST
2498 || nbr
->oi
->type
== OSPF_IFTYPE_NBMA
))
2501 /* State progression to non-terminal state */
2502 if (next_state
> old_state
&& next_state
!= NSM_Full
2503 && next_state
!= NSM_TwoWay
)
2506 if (nbr
->oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2507 ospfTrapVirtNbrStateChange(nbr
);
2509 ospfTrapNbrStateChange(nbr
);
2514 static void ospfTrapIfStateChange(struct ospf_interface
*oi
)
2516 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2518 if (IS_DEBUG_OSPF_EVENT
)
2519 zlog_info("%s: trap sent: %pI4 now %s", __func__
,
2520 &oi
->address
->u
.prefix4
,
2521 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
2523 oid_copy_addr(index
, &(oi
->address
->u
.prefix4
), IN_ADDR_SIZE
);
2524 index
[IN_ADDR_SIZE
] = 0;
2526 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2527 array_size(ospf_trap_oid
), ospf_oid
,
2528 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2529 ospfIfTrapList
, array_size(ospfIfTrapList
), IFSTATECHANGE
);
2532 static void ospfTrapVirtIfStateChange(struct ospf_interface
*oi
)
2534 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2536 zlog_info("ospfTrapVirtIfStateChange trap sent");
2538 oid_copy_addr(index
, &(oi
->address
->u
.prefix4
), IN_ADDR_SIZE
);
2539 index
[IN_ADDR_SIZE
] = 0;
2541 smux_trap(ospf_variables
, array_size(ospf_variables
), ospf_trap_oid
,
2542 array_size(ospf_trap_oid
), ospf_oid
,
2543 sizeof(ospf_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2544 ospfVirtIfTrapList
, array_size(ospfVirtIfTrapList
),
2548 static int ospf_snmp_ism_change(struct ospf_interface
*oi
, int state
,
2551 /* Terminal state or regression */
2552 if ((state
== ISM_DR
) || (state
== ISM_Backup
) || (state
== ISM_DROther
)
2553 || (state
== ISM_PointToPoint
) || (state
< old_state
)) {
2554 /* ospfVirtIfStateChange */
2555 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2556 ospfTrapVirtIfStateChange(oi
);
2557 /* ospfIfStateChange */
2559 ospfTrapIfStateChange(oi
);
2564 /* Register OSPF2-MIB. */
2565 static int ospf_snmp_init(struct thread_master
*tm
)
2567 ospf_snmp_iflist
= list_new();
2568 ospf_snmp_vl_table
= route_table_init();
2570 REGISTER_MIB("mibII/ospf", ospf_variables
, variable
, ospf_oid
);
2574 static int ospf_snmp_module_init(void)
2576 hook_register(ospf_if_update
, ospf_snmp_if_update
);
2577 hook_register(ospf_if_delete
, ospf_snmp_if_delete
);
2578 hook_register(ospf_vl_add
, ospf_snmp_vl_add
);
2579 hook_register(ospf_vl_delete
, ospf_snmp_vl_delete
);
2580 hook_register(ospf_ism_change
, ospf_snmp_ism_change
);
2581 hook_register(ospf_nsm_change
, ospf_snmp_nsm_change
);
2583 hook_register(frr_late_init
, ospf_snmp_init
);
2587 FRR_MODULE_SETUP(.name
= "ospfd_snmp", .version
= FRR_VERSION
,
2588 .description
= "ospfd AgentX SNMP module",
2589 .init
= ospf_snmp_module_init
, )