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_zebra.h"
53 #define OSPF2MIB 1,3,6,1,2,1,14
55 /* OSPF MIB General Group values. */
56 #define OSPFROUTERID 1
57 #define OSPFADMINSTAT 2
58 #define OSPFVERSIONNUMBER 3
59 #define OSPFAREABDRRTRSTATUS 4
60 #define OSPFASBDRRTRSTATUS 5
61 #define OSPFEXTERNLSACOUNT 6
62 #define OSPFEXTERNLSACKSUMSUM 7
63 #define OSPFTOSSUPPORT 8
64 #define OSPFORIGINATENEWLSAS 9
65 #define OSPFRXNEWLSAS 10
66 #define OSPFEXTLSDBLIMIT 11
67 #define OSPFMULTICASTEXTENSIONS 12
68 #define OSPFEXITOVERFLOWINTERVAL 13
69 #define OSPFDEMANDEXTENSIONS 14
71 /* OSPF MIB ospfAreaTable. */
73 #define OSPFAUTHTYPE 2
74 #define OSPFIMPORTASEXTERN 3
76 #define OSPFAREABDRRTRCOUNT 5
77 #define OSPFASBDRRTRCOUNT 6
78 #define OSPFAREALSACOUNT 7
79 #define OSPFAREALSACKSUMSUM 8
80 #define OSPFAREASUMMARY 9
81 #define OSPFAREASTATUS 10
83 /* OSPF MIB ospfStubAreaTable. */
84 #define OSPFSTUBAREAID 1
86 #define OSPFSTUBMETRIC 3
87 #define OSPFSTUBSTATUS 4
88 #define OSPFSTUBMETRICTYPE 5
90 /* OSPF MIB ospfLsdbTable. */
91 #define OSPFLSDBAREAID 1
92 #define OSPFLSDBTYPE 2
93 #define OSPFLSDBLSID 3
94 #define OSPFLSDBROUTERID 4
95 #define OSPFLSDBSEQUENCE 5
97 #define OSPFLSDBCHECKSUM 7
98 #define OSPFLSDBADVERTISEMENT 8
100 /* OSPF MIB ospfAreaRangeTable. */
101 #define OSPFAREARANGEAREAID 1
102 #define OSPFAREARANGENET 2
103 #define OSPFAREARANGEMASK 3
104 #define OSPFAREARANGESTATUS 4
105 #define OSPFAREARANGEEFFECT 5
107 /* OSPF MIB ospfHostTable. */
108 #define OSPFHOSTIPADDRESS 1
109 #define OSPFHOSTTOS 2
110 #define OSPFHOSTMETRIC 3
111 #define OSPFHOSTSTATUS 4
112 #define OSPFHOSTAREAID 5
114 /* OSPF MIB ospfIfTable. */
115 #define OSPFIFIPADDRESS 1
116 #define OSPFADDRESSLESSIF 2
117 #define OSPFIFAREAID 3
119 #define OSPFIFADMINSTAT 5
120 #define OSPFIFRTRPRIORITY 6
121 #define OSPFIFTRANSITDELAY 7
122 #define OSPFIFRETRANSINTERVAL 8
123 #define OSPFIFHELLOINTERVAL 9
124 #define OSPFIFRTRDEADINTERVAL 10
125 #define OSPFIFPOLLINTERVAL 11
126 #define OSPFIFSTATE 12
127 #define OSPFIFDESIGNATEDROUTER 13
128 #define OSPFIFBACKUPDESIGNATEDROUTER 14
129 #define OSPFIFEVENTS 15
130 #define OSPFIFAUTHKEY 16
131 #define OSPFIFSTATUS 17
132 #define OSPFIFMULTICASTFORWARDING 18
133 #define OSPFIFDEMAND 19
134 #define OSPFIFAUTHTYPE 20
136 /* OSPF MIB ospfIfMetricTable. */
137 #define OSPFIFMETRICIPADDRESS 1
138 #define OSPFIFMETRICADDRESSLESSIF 2
139 #define OSPFIFMETRICTOS 3
140 #define OSPFIFMETRICVALUE 4
141 #define OSPFIFMETRICSTATUS 5
143 /* OSPF MIB ospfVirtIfTable. */
144 #define OSPFVIRTIFAREAID 1
145 #define OSPFVIRTIFNEIGHBOR 2
146 #define OSPFVIRTIFTRANSITDELAY 3
147 #define OSPFVIRTIFRETRANSINTERVAL 4
148 #define OSPFVIRTIFHELLOINTERVAL 5
149 #define OSPFVIRTIFRTRDEADINTERVAL 6
150 #define OSPFVIRTIFSTATE 7
151 #define OSPFVIRTIFEVENTS 8
152 #define OSPFVIRTIFAUTHKEY 9
153 #define OSPFVIRTIFSTATUS 10
154 #define OSPFVIRTIFAUTHTYPE 11
156 /* OSPF MIB ospfNbrTable. */
157 #define OSPFNBRIPADDR 1
158 #define OSPFNBRADDRESSLESSINDEX 2
159 #define OSPFNBRRTRID 3
160 #define OSPFNBROPTIONS 4
161 #define OSPFNBRPRIORITY 5
162 #define OSPFNBRSTATE 6
163 #define OSPFNBREVENTS 7
164 #define OSPFNBRLSRETRANSQLEN 8
165 #define OSPFNBMANBRSTATUS 9
166 #define OSPFNBMANBRPERMANENCE 10
167 #define OSPFNBRHELLOSUPPRESSED 11
169 /* OSPF MIB ospfVirtNbrTable. */
170 #define OSPFVIRTNBRAREA 1
171 #define OSPFVIRTNBRRTRID 2
172 #define OSPFVIRTNBRIPADDR 3
173 #define OSPFVIRTNBROPTIONS 4
174 #define OSPFVIRTNBRSTATE 5
175 #define OSPFVIRTNBREVENTS 6
176 #define OSPFVIRTNBRLSRETRANSQLEN 7
177 #define OSPFVIRTNBRHELLOSUPPRESSED 8
179 /* OSPF MIB ospfExtLsdbTable. */
180 #define OSPFEXTLSDBTYPE 1
181 #define OSPFEXTLSDBLSID 2
182 #define OSPFEXTLSDBROUTERID 3
183 #define OSPFEXTLSDBSEQUENCE 4
184 #define OSPFEXTLSDBAGE 5
185 #define OSPFEXTLSDBCHECKSUM 6
186 #define OSPFEXTLSDBADVERTISEMENT 7
188 /* OSPF MIB ospfAreaAggregateTable. */
189 #define OSPFAREAAGGREGATEAREAID 1
190 #define OSPFAREAAGGREGATELSDBTYPE 2
191 #define OSPFAREAAGGREGATENET 3
192 #define OSPFAREAAGGREGATEMASK 4
193 #define OSPFAREAAGGREGATESTATUS 5
194 #define OSPFAREAAGGREGATEEFFECT 6
196 /* SYNTAX Status from OSPF-MIB. */
197 #define OSPF_STATUS_ENABLED 1
198 #define OSPF_STATUS_DISABLED 2
200 /* SNMP value hack. */
201 #define COUNTER ASN_COUNTER
202 #define INTEGER ASN_INTEGER
203 #define GAUGE ASN_GAUGE
204 #define TIMETICKS ASN_TIMETICKS
205 #define IPADDRESS ASN_IPADDRESS
206 #define STRING ASN_OCTET_STR
208 /* Because DR/DROther values are exhanged wrt RFC */
209 #define ISM_SNMP(x) \
210 (((x) == ISM_DROther) ? ISM_DR : ((x) == ISM_DR) ? ISM_DROther : (x))
212 /* Declare static local variables for convenience. */
215 /* OSPF-MIB instances. */
216 static oid ospf_oid
[] = {OSPF2MIB
};
217 static oid ospf_trap_oid
[] = {OSPF2MIB
, 16, 2}; /* Not reverse mappable! */
219 /* IP address 0.0.0.0. */
220 static struct in_addr ospf_empty_addr
= {.s_addr
= 0};
222 /* Hook functions. */
223 static u_char
*ospfGeneralGroup(struct variable
*, oid
*, size_t *, int,
224 size_t *, WriteMethod
**);
225 static u_char
*ospfAreaEntry(struct variable
*, oid
*, size_t *, int, size_t *,
227 static u_char
*ospfStubAreaEntry(struct variable
*, oid
*, size_t *, int,
228 size_t *, WriteMethod
**);
229 static u_char
*ospfLsdbEntry(struct variable
*, oid
*, size_t *, int, size_t *,
231 static u_char
*ospfAreaRangeEntry(struct variable
*, oid
*, size_t *, int,
232 size_t *, WriteMethod
**);
233 static u_char
*ospfHostEntry(struct variable
*, oid
*, size_t *, int, size_t *,
235 static u_char
*ospfIfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
237 static u_char
*ospfIfMetricEntry(struct variable
*, oid
*, size_t *, int,
238 size_t *, WriteMethod
**);
239 static u_char
*ospfVirtIfEntry(struct variable
*, oid
*, size_t *, int,
240 size_t *, WriteMethod
**);
241 static u_char
*ospfNbrEntry(struct variable
*, oid
*, size_t *, int, size_t *,
243 static u_char
*ospfVirtNbrEntry(struct variable
*, oid
*, size_t *, int,
244 size_t *, WriteMethod
**);
245 static u_char
*ospfExtLsdbEntry(struct variable
*, oid
*, size_t *, int,
246 size_t *, WriteMethod
**);
247 static u_char
*ospfAreaAggregateEntry(struct variable
*, oid
*, size_t *, int,
248 size_t *, WriteMethod
**);
250 static struct variable ospf_variables
[] = {
251 /* OSPF general variables */
252 {OSPFROUTERID
, IPADDRESS
, RWRITE
, ospfGeneralGroup
, 2, {1, 1}},
253 {OSPFADMINSTAT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 2}},
254 {OSPFVERSIONNUMBER
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 3}},
255 {OSPFAREABDRRTRSTATUS
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 4}},
256 {OSPFASBDRRTRSTATUS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 5}},
257 {OSPFEXTERNLSACOUNT
, GAUGE
, RONLY
, ospfGeneralGroup
, 2, {1, 6}},
258 {OSPFEXTERNLSACKSUMSUM
, INTEGER
, RONLY
, ospfGeneralGroup
, 2, {1, 7}},
259 {OSPFTOSSUPPORT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 8}},
260 {OSPFORIGINATENEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 9}},
261 {OSPFRXNEWLSAS
, COUNTER
, RONLY
, ospfGeneralGroup
, 2, {1, 10}},
262 {OSPFEXTLSDBLIMIT
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 11}},
263 {OSPFMULTICASTEXTENSIONS
,
269 {OSPFEXITOVERFLOWINTERVAL
,
275 {OSPFDEMANDEXTENSIONS
, INTEGER
, RWRITE
, ospfGeneralGroup
, 2, {1, 14}},
277 /* OSPF area data structure. */
278 {OSPFAREAID
, IPADDRESS
, RONLY
, ospfAreaEntry
, 3, {2, 1, 1}},
279 {OSPFAUTHTYPE
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 2}},
280 {OSPFIMPORTASEXTERN
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 3}},
281 {OSPFSPFRUNS
, COUNTER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 4}},
282 {OSPFAREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 5}},
283 {OSPFASBDRRTRCOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 6}},
284 {OSPFAREALSACOUNT
, GAUGE
, RONLY
, ospfAreaEntry
, 3, {2, 1, 7}},
285 {OSPFAREALSACKSUMSUM
, INTEGER
, RONLY
, ospfAreaEntry
, 3, {2, 1, 8}},
286 {OSPFAREASUMMARY
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 9}},
287 {OSPFAREASTATUS
, INTEGER
, RWRITE
, ospfAreaEntry
, 3, {2, 1, 10}},
289 /* OSPF stub area information. */
290 {OSPFSTUBAREAID
, IPADDRESS
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 1}},
291 {OSPFSTUBTOS
, INTEGER
, RONLY
, ospfStubAreaEntry
, 3, {3, 1, 2}},
292 {OSPFSTUBMETRIC
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 3}},
293 {OSPFSTUBSTATUS
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 4}},
294 {OSPFSTUBMETRICTYPE
, INTEGER
, RWRITE
, ospfStubAreaEntry
, 3, {3, 1, 5}},
296 /* OSPF link state database. */
297 {OSPFLSDBAREAID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 1}},
298 {OSPFLSDBTYPE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 2}},
299 {OSPFLSDBLSID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 3}},
300 {OSPFLSDBROUTERID
, IPADDRESS
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 4}},
301 {OSPFLSDBSEQUENCE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 5}},
302 {OSPFLSDBAGE
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 6}},
303 {OSPFLSDBCHECKSUM
, INTEGER
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 7}},
304 {OSPFLSDBADVERTISEMENT
, STRING
, RONLY
, ospfLsdbEntry
, 3, {4, 1, 8}},
306 /* Area range table. */
307 {OSPFAREARANGEAREAID
,
313 {OSPFAREARANGENET
, IPADDRESS
, RONLY
, ospfAreaRangeEntry
, 3, {5, 1, 2}},
320 {OSPFAREARANGESTATUS
,
326 {OSPFAREARANGEEFFECT
,
333 /* OSPF host table. */
334 {OSPFHOSTIPADDRESS
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 1}},
335 {OSPFHOSTTOS
, INTEGER
, RONLY
, ospfHostEntry
, 3, {6, 1, 2}},
336 {OSPFHOSTMETRIC
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 3}},
337 {OSPFHOSTSTATUS
, INTEGER
, RWRITE
, ospfHostEntry
, 3, {6, 1, 4}},
338 {OSPFHOSTAREAID
, IPADDRESS
, RONLY
, ospfHostEntry
, 3, {6, 1, 5}},
340 /* OSPF interface table. */
341 {OSPFIFIPADDRESS
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 1}},
342 {OSPFADDRESSLESSIF
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 2}},
343 {OSPFIFAREAID
, IPADDRESS
, RWRITE
, ospfIfEntry
, 3, {7, 1, 3}},
344 {OSPFIFTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 4}},
345 {OSPFIFADMINSTAT
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 5}},
346 {OSPFIFRTRPRIORITY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 6}},
347 {OSPFIFTRANSITDELAY
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 7}},
348 {OSPFIFRETRANSINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 8}},
349 {OSPFIFHELLOINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 9}},
350 {OSPFIFRTRDEADINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 10}},
351 {OSPFIFPOLLINTERVAL
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 11}},
352 {OSPFIFSTATE
, INTEGER
, RONLY
, ospfIfEntry
, 3, {7, 1, 12}},
353 {OSPFIFDESIGNATEDROUTER
, IPADDRESS
, RONLY
, ospfIfEntry
, 3, {7, 1, 13}},
354 {OSPFIFBACKUPDESIGNATEDROUTER
,
360 {OSPFIFEVENTS
, COUNTER
, RONLY
, ospfIfEntry
, 3, {7, 1, 15}},
361 {OSPFIFAUTHKEY
, STRING
, RWRITE
, ospfIfEntry
, 3, {7, 1, 16}},
362 {OSPFIFSTATUS
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 17}},
363 {OSPFIFMULTICASTFORWARDING
,
369 {OSPFIFDEMAND
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 19}},
370 {OSPFIFAUTHTYPE
, INTEGER
, RWRITE
, ospfIfEntry
, 3, {7, 1, 20}},
372 /* OSPF interface metric table. */
373 {OSPFIFMETRICIPADDRESS
,
379 {OSPFIFMETRICADDRESSLESSIF
,
385 {OSPFIFMETRICTOS
, INTEGER
, RONLY
, ospfIfMetricEntry
, 3, {8, 1, 3}},
386 {OSPFIFMETRICVALUE
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 4}},
387 {OSPFIFMETRICSTATUS
, INTEGER
, RWRITE
, ospfIfMetricEntry
, 3, {8, 1, 5}},
389 /* OSPF virtual interface table. */
390 {OSPFVIRTIFAREAID
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 1}},
391 {OSPFVIRTIFNEIGHBOR
, IPADDRESS
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 2}},
392 {OSPFVIRTIFTRANSITDELAY
,
398 {OSPFVIRTIFRETRANSINTERVAL
,
404 {OSPFVIRTIFHELLOINTERVAL
,
410 {OSPFVIRTIFRTRDEADINTERVAL
,
416 {OSPFVIRTIFSTATE
, INTEGER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 7}},
417 {OSPFVIRTIFEVENTS
, COUNTER
, RONLY
, ospfVirtIfEntry
, 3, {9, 1, 8}},
418 {OSPFVIRTIFAUTHKEY
, STRING
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 9}},
419 {OSPFVIRTIFSTATUS
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 10}},
420 {OSPFVIRTIFAUTHTYPE
, INTEGER
, RWRITE
, ospfVirtIfEntry
, 3, {9, 1, 11}},
422 /* OSPF neighbor table. */
423 {OSPFNBRIPADDR
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 1}},
424 {OSPFNBRADDRESSLESSINDEX
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 2}},
425 {OSPFNBRRTRID
, IPADDRESS
, RONLY
, ospfNbrEntry
, 3, {10, 1, 3}},
426 {OSPFNBROPTIONS
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 4}},
427 {OSPFNBRPRIORITY
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 5}},
428 {OSPFNBRSTATE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 6}},
429 {OSPFNBREVENTS
, COUNTER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 7}},
430 {OSPFNBRLSRETRANSQLEN
, GAUGE
, RONLY
, ospfNbrEntry
, 3, {10, 1, 8}},
431 {OSPFNBMANBRSTATUS
, INTEGER
, RWRITE
, ospfNbrEntry
, 3, {10, 1, 9}},
432 {OSPFNBMANBRPERMANENCE
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 10}},
433 {OSPFNBRHELLOSUPPRESSED
, INTEGER
, RONLY
, ospfNbrEntry
, 3, {10, 1, 11}},
435 /* OSPF virtual neighbor table. */
436 {OSPFVIRTNBRAREA
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 1}},
437 {OSPFVIRTNBRRTRID
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 2}},
438 {OSPFVIRTNBRIPADDR
, IPADDRESS
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 3}},
439 {OSPFVIRTNBROPTIONS
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 4}},
440 {OSPFVIRTNBRSTATE
, INTEGER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 5}},
441 {OSPFVIRTNBREVENTS
, COUNTER
, RONLY
, ospfVirtNbrEntry
, 3, {11, 1, 6}},
442 {OSPFVIRTNBRLSRETRANSQLEN
,
448 {OSPFVIRTNBRHELLOSUPPRESSED
,
455 /* OSPF link state database, external. */
456 {OSPFEXTLSDBTYPE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 1}},
457 {OSPFEXTLSDBLSID
, IPADDRESS
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 2}},
458 {OSPFEXTLSDBROUTERID
,
464 {OSPFEXTLSDBSEQUENCE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 4}},
465 {OSPFEXTLSDBAGE
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 5}},
466 {OSPFEXTLSDBCHECKSUM
, INTEGER
, RONLY
, ospfExtLsdbEntry
, 3, {12, 1, 6}},
467 {OSPFEXTLSDBADVERTISEMENT
,
474 /* OSPF area aggregate table. */
475 {OSPFAREAAGGREGATEAREAID
,
478 ospfAreaAggregateEntry
,
481 {OSPFAREAAGGREGATELSDBTYPE
,
484 ospfAreaAggregateEntry
,
487 {OSPFAREAAGGREGATENET
,
490 ospfAreaAggregateEntry
,
493 {OSPFAREAAGGREGATEMASK
,
496 ospfAreaAggregateEntry
,
499 {OSPFAREAAGGREGATESTATUS
,
502 ospfAreaAggregateEntry
,
505 {OSPFAREAAGGREGATEEFFECT
,
508 ospfAreaAggregateEntry
,
512 /* The administrative status of OSPF. When OSPF is enbled on at least
513 one interface return 1. */
514 static int ospf_admin_stat(struct ospf
*ospf
)
516 struct listnode
*node
;
517 struct ospf_interface
*oi
;
522 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
523 if (oi
&& oi
->address
)
529 static u_char
*ospfGeneralGroup(struct variable
*v
, oid
*name
, size_t *length
,
530 int exact
, size_t *var_len
,
531 WriteMethod
**write_method
)
535 ospf
= ospf_lookup();
537 /* Check whether the instance identifier is valid */
538 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
542 /* Return the current value of the variable */
544 case OSPFROUTERID
: /* 1 */
545 /* Router-ID of this OSPF instance. */
547 return SNMP_IPADDRESS(ospf
->router_id
);
549 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
);
558 case OSPFVERSIONNUMBER
: /* 3 */
559 /* OSPF version 2. */
560 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
);
569 case OSPFASBDRRTRSTATUS
: /* 5 */
570 /* AS Border router status. */
571 if (ospf
&& CHECK_FLAG(ospf
->flags
, OSPF_FLAG_ASBR
))
572 return SNMP_INTEGER(SNMP_TRUE
);
574 return SNMP_INTEGER(SNMP_FALSE
);
576 case OSPFEXTERNLSACOUNT
: /* 6 */
577 /* External LSA counts. */
579 return SNMP_INTEGER(ospf_lsdb_count_all(ospf
->lsdb
));
581 return SNMP_INTEGER(0);
583 case OSPFEXTERNLSACKSUMSUM
: /* 7 */
584 /* External LSA checksum. */
585 return SNMP_INTEGER(0);
587 case OSPFTOSSUPPORT
: /* 8 */
588 /* TOS is not supported. */
589 return SNMP_INTEGER(SNMP_FALSE
);
591 case OSPFORIGINATENEWLSAS
: /* 9 */
592 /* The number of new link-state advertisements. */
594 return SNMP_INTEGER(ospf
->lsa_originate_count
);
596 return SNMP_INTEGER(0);
598 case OSPFRXNEWLSAS
: /* 10 */
599 /* The number of link-state advertisements received determined
600 to be new instantiations. */
602 return SNMP_INTEGER(ospf
->rx_lsa_count
);
604 return SNMP_INTEGER(0);
606 case OSPFEXTLSDBLIMIT
: /* 11 */
607 /* There is no limit for the number of non-default
609 return SNMP_INTEGER(-1);
611 case OSPFMULTICASTEXTENSIONS
: /* 12 */
612 /* Multicast Extensions to OSPF is not supported. */
613 return SNMP_INTEGER(0);
615 case OSPFEXITOVERFLOWINTERVAL
: /* 13 */
616 /* Overflow is not supported. */
617 return SNMP_INTEGER(0);
619 case OSPFDEMANDEXTENSIONS
: /* 14 */
620 /* Demand routing is not supported. */
621 return SNMP_INTEGER(SNMP_FALSE
);
629 static struct ospf_area
*
630 ospf_area_lookup_next(struct ospf
*ospf
, struct in_addr
*area_id
, int first
)
632 struct ospf_area
*area
;
633 struct listnode
*node
;
639 node
= listhead(ospf
->areas
);
641 area
= listgetdata(node
);
642 *area_id
= area
->area_id
;
647 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
648 if (ntohl(area
->area_id
.s_addr
) > ntohl(area_id
->s_addr
)) {
649 *area_id
= area
->area_id
;
656 static struct ospf_area
*ospfAreaLookup(struct variable
*v
, oid name
[],
657 size_t *length
, struct in_addr
*addr
,
661 struct ospf_area
*area
;
664 ospf
= ospf_lookup();
669 /* Length is insufficient to lookup OSPF area. */
670 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
673 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
675 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
679 len
= *length
- v
->namelen
;
683 oid2in_addr(name
+ v
->namelen
, len
, addr
);
685 area
= ospf_area_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
690 oid_copy_addr(name
+ v
->namelen
, addr
, sizeof(struct in_addr
));
691 *length
= sizeof(struct in_addr
) + v
->namelen
;
698 static u_char
*ospfAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
699 int exact
, size_t *var_len
,
700 WriteMethod
**write_method
)
702 struct ospf_area
*area
;
705 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
709 memset(&addr
, 0, sizeof(struct in_addr
));
711 area
= ospfAreaLookup(v
, name
, length
, &addr
, exact
);
715 /* Return the current value of the variable */
717 case OSPFAREAID
: /* 1 */
718 return SNMP_IPADDRESS(area
->area_id
);
720 case OSPFAUTHTYPE
: /* 2 */
721 return SNMP_INTEGER(area
->auth_type
);
723 case OSPFIMPORTASEXTERN
: /* 3 */
724 return SNMP_INTEGER(area
->external_routing
+ 1);
726 case OSPFSPFRUNS
: /* 4 */
727 return SNMP_INTEGER(area
->spf_calculation
);
729 case OSPFAREABDRRTRCOUNT
: /* 5 */
730 return SNMP_INTEGER(area
->abr_count
);
732 case OSPFASBDRRTRCOUNT
: /* 6 */
733 return SNMP_INTEGER(area
->asbr_count
);
735 case OSPFAREALSACOUNT
: /* 7 */
736 return SNMP_INTEGER(area
->lsdb
->total
);
738 case OSPFAREALSACKSUMSUM
: /* 8 */
739 return SNMP_INTEGER(0);
741 case OSPFAREASUMMARY
: /* 9 */
743 /* clang-format off */
744 #define OSPF_noAreaSummary 1
745 #define OSPF_sendAreaSummary 2
746 if (area
->no_summary
)
747 return SNMP_INTEGER(OSPF_noAreaSummary
);
749 return SNMP_INTEGER(OSPF_sendAreaSummary
);
751 case OSPFAREASTATUS
: /* 10 */
752 return SNMP_INTEGER(SNMP_VALID
);
761 static struct ospf_area
*ospf_stub_area_lookup_next(struct in_addr
*area_id
,
764 struct ospf_area
*area
;
765 struct listnode
*node
;
768 ospf
= ospf_lookup();
772 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
773 if (area
->external_routing
== OSPF_AREA_STUB
) {
775 *area_id
= area
->area_id
;
777 } else if (ntohl(area
->area_id
.s_addr
)
778 > ntohl(area_id
->s_addr
)) {
779 *area_id
= area
->area_id
;
787 static struct ospf_area
*ospfStubAreaLookup(struct variable
*v
, oid name
[],
789 struct in_addr
*addr
, int exact
)
792 struct ospf_area
*area
;
795 ospf
= ospf_lookup();
801 /* ospfStubAreaID + ospfStubTOS. */
802 if (*length
!= v
->namelen
+ sizeof(struct in_addr
) + 1)
805 /* Check ospfStubTOS is zero. */
806 if (name
[*length
- 1] != 0)
809 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
811 area
= ospf_area_lookup_by_area_id(ospf
, *addr
);
813 if (area
->external_routing
== OSPF_AREA_STUB
)
818 len
= *length
- v
->namelen
;
822 oid2in_addr(name
+ v
->namelen
, len
, addr
);
824 area
= ospf_stub_area_lookup_next(addr
, len
== 0 ? 1 : 0);
829 oid_copy_addr(name
+ v
->namelen
, addr
, sizeof(struct in_addr
));
831 name
[v
->namelen
+ sizeof(struct in_addr
)] = 0;
832 *length
= v
->namelen
+ sizeof(struct in_addr
) + 1;
839 static u_char
*ospfStubAreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
840 int exact
, size_t *var_len
,
841 WriteMethod
**write_method
)
843 struct ospf_area
*area
;
846 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
850 memset(&addr
, 0, sizeof(struct in_addr
));
852 area
= ospfStubAreaLookup(v
, name
, length
, &addr
, exact
);
856 /* Return the current value of the variable */
858 case OSPFSTUBAREAID
: /* 1 */
859 /* OSPF stub area id. */
860 return SNMP_IPADDRESS(area
->area_id
);
862 case OSPFSTUBTOS
: /* 2 */
863 /* TOS value is not supported. */
864 return SNMP_INTEGER(0);
866 case OSPFSTUBMETRIC
: /* 3 */
867 /* Default cost to stub area. */
868 return SNMP_INTEGER(area
->default_cost
);
870 case OSPFSTUBSTATUS
: /* 4 */
871 /* Status of the stub area. */
872 return SNMP_INTEGER(SNMP_VALID
);
874 case OSPFSTUBMETRICTYPE
: /* 5 */
875 /* OSPF Metric type. */
876 #define OSPF_ospfMetric 1
877 #define OSPF_comparableCost 2
878 #define OSPF_nonComparable 3
879 return SNMP_INTEGER(OSPF_ospfMetric
);
888 static struct ospf_lsa
*lsdb_lookup_next(struct ospf_area
*area
, u_char
*type
,
889 int type_next
, struct in_addr
*ls_id
,
891 struct in_addr
*router_id
,
894 struct ospf_lsa
*lsa
;
902 /* Sanity check, if LSA type unknwon
903 merley skip any LSA */
904 if ((i
< OSPF_MIN_LSA
) || (i
>= OSPF_MAX_LSA
)) {
905 zlog_debug("Strange request with LSA type %d\n", i
);
909 for (; i
< OSPF_MAX_LSA
; i
++) {
912 lsa
= ospf_lsdb_lookup_by_id_next(area
->lsdb
, *type
, *ls_id
,
913 *router_id
, ls_id_next
);
922 static struct ospf_lsa
*ospfLsdbLookup(struct variable
*v
, oid
*name
,
923 size_t *length
, struct in_addr
*area_id
,
924 u_char
*type
, struct in_addr
*ls_id
,
925 struct in_addr
*router_id
, int exact
)
928 struct ospf_area
*area
;
929 struct ospf_lsa
*lsa
;
937 ospf
= ospf_lookup();
939 #define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
942 /* Area ID + Type + LS ID + Router ID. */
943 if (*length
- v
->namelen
!= OSPF_LSDB_ENTRY_OFFSET
)
946 /* Set OID offset for Area ID. */
947 offset
= name
+ v
->namelen
;
949 /* Lookup area first. */
950 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
951 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
954 offset
+= IN_ADDR_SIZE
;
961 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
962 offset
+= IN_ADDR_SIZE
;
965 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
968 return ospf_lsdb_lookup_by_id(area
->lsdb
, *type
, *ls_id
,
971 /* Get variable length. */
972 offset
= name
+ v
->namelen
;
973 offsetlen
= *length
- v
->namelen
;
976 if (len
> (int)IN_ADDR_SIZE
)
979 oid2in_addr(offset
, len
, area_id
);
981 /* First we search area. */
982 if (len
== IN_ADDR_SIZE
)
983 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
985 area
= ospf_area_lookup_next(ospf
, area_id
, 1);
991 /* Next we lookup type. */
1013 if (len
> (int)IN_ADDR_SIZE
)
1016 oid2in_addr(offset
, len
, ls_id
);
1020 offset
+= IN_ADDR_SIZE
;
1021 offsetlen
-= IN_ADDR_SIZE
;
1028 if (len
> (int)IN_ADDR_SIZE
)
1031 oid2in_addr(offset
, len
, router_id
);
1034 lsa
= lsdb_lookup_next(area
, type
, type_next
, ls_id
,
1035 ls_id_next
, router_id
,
1039 /* Fill in length. */
1040 *length
= v
->namelen
+ OSPF_LSDB_ENTRY_OFFSET
;
1042 /* Fill in value. */
1043 offset
= name
+ v
->namelen
;
1044 oid_copy_addr(offset
, area_id
, IN_ADDR_SIZE
);
1045 offset
+= IN_ADDR_SIZE
;
1046 *offset
= lsa
->data
->type
;
1048 oid_copy_addr(offset
, &lsa
->data
->id
,
1050 offset
+= IN_ADDR_SIZE
;
1051 oid_copy_addr(offset
, &lsa
->data
->adv_router
,
1056 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1062 static u_char
*ospfLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
1063 int exact
, size_t *var_len
,
1064 WriteMethod
**write_method
)
1066 struct ospf_lsa
*lsa
;
1067 struct lsa_header
*lsah
;
1068 struct in_addr area_id
;
1070 struct in_addr ls_id
;
1071 struct in_addr router_id
;
1074 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1078 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1079 ospfLsdbLsid, ospfLsdbRouterId } */
1081 memset(&area_id
, 0, sizeof(struct in_addr
));
1083 memset(&ls_id
, 0, sizeof(struct in_addr
));
1084 memset(&router_id
, 0, sizeof(struct in_addr
));
1086 /* Check OSPF instance. */
1087 ospf
= ospf_lookup();
1091 lsa
= ospfLsdbLookup(v
, name
, length
, &area_id
, &type
, &ls_id
,
1098 /* Return the current value of the variable */
1100 case OSPFLSDBAREAID
: /* 1 */
1101 return SNMP_IPADDRESS(lsa
->area
->area_id
);
1103 case OSPFLSDBTYPE
: /* 2 */
1104 return SNMP_INTEGER(lsah
->type
);
1106 case OSPFLSDBLSID
: /* 3 */
1107 return SNMP_IPADDRESS(lsah
->id
);
1109 case OSPFLSDBROUTERID
: /* 4 */
1110 return SNMP_IPADDRESS(lsah
->adv_router
);
1112 case OSPFLSDBSEQUENCE
: /* 5 */
1113 return SNMP_INTEGER(lsah
->ls_seqnum
);
1115 case OSPFLSDBAGE
: /* 6 */
1116 return SNMP_INTEGER(lsah
->ls_age
);
1118 case OSPFLSDBCHECKSUM
: /* 7 */
1119 return SNMP_INTEGER(lsah
->checksum
);
1121 case OSPFLSDBADVERTISEMENT
: /* 8 */
1122 *var_len
= ntohs(lsah
->length
);
1123 return (u_char
*)lsah
;
1132 static struct ospf_area_range
*ospfAreaRangeLookup(struct variable
*v
,
1133 oid
*name
, size_t *length
,
1134 struct in_addr
*area_id
,
1135 struct in_addr
*range_net
,
1142 struct ospf_area
*area
;
1143 struct ospf_area_range
*range
;
1144 struct prefix_ipv4 p
;
1146 p
.prefixlen
= IPV4_MAX_BITLEN
;
1148 ospf
= ospf_lookup();
1151 /* Area ID + Range Network. */
1152 if (v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
!= *length
)
1155 /* Set OID offset for Area ID. */
1156 offset
= name
+ v
->namelen
;
1158 /* Lookup area first. */
1159 oid2in_addr(offset
, IN_ADDR_SIZE
, area_id
);
1161 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1165 offset
+= IN_ADDR_SIZE
;
1167 /* Lookup area range. */
1168 oid2in_addr(offset
, IN_ADDR_SIZE
, range_net
);
1169 p
.prefix
= *range_net
;
1171 return ospf_area_range_lookup(area
, &p
);
1173 /* Set OID offset for Area ID. */
1174 offset
= name
+ v
->namelen
;
1175 offsetlen
= *length
- v
->namelen
;
1178 if (len
> (int)IN_ADDR_SIZE
)
1181 oid2in_addr(offset
, len
, area_id
);
1183 /* First we search area. */
1184 if (len
== IN_ADDR_SIZE
)
1185 area
= ospf_area_lookup_by_area_id(ospf
, *area_id
);
1187 area
= ospf_area_lookup_next(ospf
, area_id
,
1194 offset
+= IN_ADDR_SIZE
;
1195 offsetlen
-= IN_ADDR_SIZE
;
1200 if (len
> (int)IN_ADDR_SIZE
)
1203 oid2in_addr(offset
, len
, range_net
);
1205 range
= ospf_area_range_lookup_next(area
, range_net
,
1209 /* Fill in length. */
1210 *length
= v
->namelen
+ IN_ADDR_SIZE
1213 /* Fill in value. */
1214 offset
= name
+ v
->namelen
;
1215 oid_copy_addr(offset
, area_id
, IN_ADDR_SIZE
);
1216 offset
+= IN_ADDR_SIZE
;
1217 oid_copy_addr(offset
, range_net
, IN_ADDR_SIZE
);
1221 } while ((area
= ospf_area_lookup_next(ospf
, area_id
, 0))
1227 static u_char
*ospfAreaRangeEntry(struct variable
*v
, oid
*name
, size_t *length
,
1228 int exact
, size_t *var_len
,
1229 WriteMethod
**write_method
)
1231 struct ospf_area_range
*range
;
1232 struct in_addr area_id
;
1233 struct in_addr range_net
;
1234 struct in_addr mask
;
1237 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1241 /* Check OSPF instance. */
1242 ospf
= ospf_lookup();
1246 memset(&area_id
, 0, IN_ADDR_SIZE
);
1247 memset(&range_net
, 0, IN_ADDR_SIZE
);
1249 range
= ospfAreaRangeLookup(v
, name
, length
, &area_id
, &range_net
,
1254 /* Convert prefixlen to network mask format. */
1255 masklen2ip(range
->subst_masklen
, &mask
);
1257 /* Return the current value of the variable */
1259 case OSPFAREARANGEAREAID
: /* 1 */
1260 return SNMP_IPADDRESS(area_id
);
1262 case OSPFAREARANGENET
: /* 2 */
1263 return SNMP_IPADDRESS(range_net
);
1265 case OSPFAREARANGEMASK
: /* 3 */
1266 return SNMP_IPADDRESS(mask
);
1268 case OSPFAREARANGESTATUS
: /* 4 */
1269 return SNMP_INTEGER(SNMP_VALID
);
1271 case OSPFAREARANGEEFFECT
: /* 5 */
1273 /* clang-format off */
1274 #define OSPF_advertiseMatching 1
1275 #define OSPF_doNotAdvertiseMatching 2
1276 return SNMP_INTEGER(OSPF_advertiseMatching
);
1285 static struct ospf_nbr_nbma
*ospfHostLookup(struct variable
*v
, oid
*name
,
1287 struct in_addr
*addr
, int exact
)
1290 struct ospf_nbr_nbma
*nbr_nbma
;
1293 ospf
= ospf_lookup();
1298 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1299 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1302 /* Check ospfHostTOS. */
1303 if (name
[*length
- 1] != 0)
1306 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, addr
);
1308 nbr_nbma
= ospf_nbr_nbma_lookup(ospf
, *addr
);
1312 len
= *length
- v
->namelen
;
1316 oid2in_addr(name
+ v
->namelen
, len
, addr
);
1319 ospf_nbr_nbma_lookup_next(ospf
, addr
, len
== 0 ? 1 : 0);
1321 if (nbr_nbma
== NULL
)
1324 oid_copy_addr(name
+ v
->namelen
, addr
, IN_ADDR_SIZE
);
1327 name
[v
->namelen
+ IN_ADDR_SIZE
] = 0;
1329 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1336 static u_char
*ospfHostEntry(struct variable
*v
, oid
*name
, size_t *length
,
1337 int exact
, size_t *var_len
,
1338 WriteMethod
**write_method
)
1340 struct ospf_nbr_nbma
*nbr_nbma
;
1341 struct ospf_interface
*oi
;
1342 struct in_addr addr
;
1345 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1349 /* Check OSPF instance. */
1350 ospf
= ospf_lookup();
1354 memset(&addr
, 0, sizeof(struct in_addr
));
1356 nbr_nbma
= ospfHostLookup(v
, name
, length
, &addr
, exact
);
1357 if (nbr_nbma
== NULL
)
1362 /* Return the current value of the variable */
1364 case OSPFHOSTIPADDRESS
: /* 1 */
1365 return SNMP_IPADDRESS(nbr_nbma
->addr
);
1367 case OSPFHOSTTOS
: /* 2 */
1368 return SNMP_INTEGER(0);
1370 case OSPFHOSTMETRIC
: /* 3 */
1372 return SNMP_INTEGER(oi
->output_cost
);
1374 return SNMP_INTEGER(1);
1376 case OSPFHOSTSTATUS
: /* 4 */
1377 return SNMP_INTEGER(SNMP_VALID
);
1379 case OSPFHOSTAREAID
: /* 5 */
1381 return SNMP_IPADDRESS(oi
->area
->area_id
);
1383 return SNMP_IPADDRESS(ospf_empty_addr
);
1392 static struct list
*ospf_snmp_iflist
;
1394 struct ospf_snmp_if
{
1395 struct in_addr addr
;
1397 struct interface
*ifp
;
1400 static struct ospf_snmp_if
*ospf_snmp_if_new(void)
1402 return XCALLOC(MTYPE_TMP
, sizeof(struct ospf_snmp_if
));
1405 static void ospf_snmp_if_free(struct ospf_snmp_if
*osif
)
1407 XFREE(MTYPE_TMP
, osif
);
1410 static int ospf_snmp_if_delete(struct interface
*ifp
)
1412 struct listnode
*node
, *nnode
;
1413 struct ospf_snmp_if
*osif
;
1415 for (ALL_LIST_ELEMENTS(ospf_snmp_iflist
, node
, nnode
, osif
)) {
1416 if (osif
->ifp
== ifp
) {
1417 list_delete_node(ospf_snmp_iflist
, node
);
1418 ospf_snmp_if_free(osif
);
1425 static int ospf_snmp_if_update(struct interface
*ifp
)
1427 struct listnode
*node
;
1428 struct listnode
*pn
;
1429 struct connected
*ifc
;
1431 struct ospf_snmp_if
*osif
;
1432 struct in_addr
*addr
;
1435 ospf_snmp_if_delete(ifp
);
1441 /* Lookup first IPv4 address entry. */
1442 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1443 p
= CONNECTED_ID(ifc
);
1445 if (p
->family
== AF_INET
) {
1446 addr
= &p
->u
.prefix4
;
1451 ifindex
= ifp
->ifindex
;
1453 /* Add interface to the list. */
1455 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1457 /* Usual interfaces --> Sort them based on interface
1459 if (ntohl(osif
->addr
.s_addr
) > ntohl(addr
->s_addr
))
1462 /* Unnumbered interfaces --> Sort them based on
1463 * interface indexes */
1464 if (osif
->addr
.s_addr
!= 0 || osif
->ifindex
> ifindex
)
1470 osif
= ospf_snmp_if_new();
1471 if (addr
) /* Usual interface */
1475 /* This field is used for storing ospfAddressLessIf OID value,
1476 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1477 * usual interface */
1479 } else /* Unnumbered interface */
1480 osif
->ifindex
= ifindex
;
1483 listnode_add_after(ospf_snmp_iflist
, pn
, osif
);
1487 static int ospf_snmp_is_if_have_addr(struct interface
*ifp
)
1489 struct listnode
*nn
;
1490 struct connected
*ifc
;
1492 /* Is this interface having any connected IPv4 address ? */
1493 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, nn
, ifc
)) {
1494 if (CONNECTED_PREFIX(ifc
)->family
== AF_INET
)
1501 static struct ospf_interface
*ospf_snmp_if_lookup(struct in_addr
*ifaddr
,
1504 struct listnode
*node
;
1505 struct ospf_snmp_if
*osif
;
1506 struct ospf_interface
*oi
= NULL
;
1507 struct ospf
*ospf
= ospf_lookup();
1509 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, node
, osif
)) {
1510 if (ifaddr
->s_addr
) {
1511 if (IPV4_ADDR_SAME(&osif
->addr
, ifaddr
))
1512 oi
= ospf_if_lookup_by_local_addr(
1513 ospf
, osif
->ifp
, *ifaddr
);
1515 if (osif
->ifindex
== *ifindex
)
1516 oi
= ospf_if_lookup_by_local_addr(
1517 ospf
, osif
->ifp
, *ifaddr
);
1523 static struct ospf_interface
*ospf_snmp_if_lookup_next(struct in_addr
*ifaddr
,
1526 ifindex_t ifindex_next
)
1528 struct ospf_snmp_if
*osif
;
1529 struct listnode
*nn
;
1530 struct ospf
*ospf
= ospf_lookup();
1531 struct ospf_interface
*oi
= NULL
;
1536 /* No instance is specified --> Return the first OSPF interface */
1538 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1539 osif
= listgetdata(nn
);
1540 *ifaddr
= osif
->addr
;
1541 *ifindex
= osif
->ifindex
;
1542 /* Because no instance is specified, we don't care about
1544 * interface (usual or unnumbered), just returning the
1547 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1555 /* An instance is specified --> Return the next OSPF interface */
1556 for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist
, nn
, osif
)) {
1557 /* Usual interface */
1558 if (ifaddr
->s_addr
) {
1559 /* The interface must have valid AF_INET connected
1561 /* it must have lager IPv4 address value than the lookup
1563 if ((ospf_snmp_is_if_have_addr(osif
->ifp
))
1564 && (ntohl(osif
->addr
.s_addr
)
1565 > ntohl(ifaddr
->s_addr
))) {
1566 *ifaddr
= osif
->addr
;
1567 *ifindex
= osif
->ifindex
;
1569 /* and it must be an OSPF interface */
1570 oi
= ospf_if_lookup_by_local_addr(
1571 ospf
, osif
->ifp
, *ifaddr
);
1576 /* Unnumbered interface */
1578 /* The interface must NOT have valid AF_INET connected
1580 /* it must have lager interface index than the lookup
1582 if ((!ospf_snmp_is_if_have_addr(osif
->ifp
))
1583 && (osif
->ifindex
> *ifindex
)) {
1584 *ifaddr
= osif
->addr
;
1585 *ifindex
= osif
->ifindex
;
1587 /* and it must be an OSPF interface */
1588 oi
= ospf_if_lookup_by_local_addr(ospf
, osif
->ifp
,
1597 static int ospf_snmp_iftype(struct interface
*ifp
)
1599 #define ospf_snmp_iftype_broadcast 1
1600 #define ospf_snmp_iftype_nbma 2
1601 #define ospf_snmp_iftype_pointToPoint 3
1602 #define ospf_snmp_iftype_pointToMultipoint 5
1603 if (if_is_broadcast(ifp
))
1604 return ospf_snmp_iftype_broadcast
;
1605 if (if_is_pointopoint(ifp
))
1606 return ospf_snmp_iftype_pointToPoint
;
1607 return ospf_snmp_iftype_broadcast
;
1610 static struct ospf_interface
*ospfIfLookup(struct variable
*v
, oid
*name
,
1612 struct in_addr
*ifaddr
,
1613 ifindex_t
*ifindex
, int exact
)
1616 int ifaddr_next
= 0;
1617 ifindex_t ifindex_next
= 0;
1618 struct ospf_interface
*oi
;
1622 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
1625 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1626 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1628 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1630 len
= *length
- v
->namelen
;
1631 if (len
>= IN_ADDR_SIZE
)
1636 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1638 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1645 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1647 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1650 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
1651 offset
= name
+ v
->namelen
;
1652 oid_copy_addr(offset
, ifaddr
, IN_ADDR_SIZE
);
1653 offset
+= IN_ADDR_SIZE
;
1661 static u_char
*ospfIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1662 int exact
, size_t *var_len
,
1663 WriteMethod
**write_method
)
1666 struct in_addr ifaddr
;
1667 struct ospf_interface
*oi
;
1670 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1675 memset(&ifaddr
, 0, sizeof(struct in_addr
));
1677 /* Check OSPF instance. */
1678 ospf
= ospf_lookup();
1682 oi
= ospfIfLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1686 /* Return the current value of the variable */
1688 case OSPFIFIPADDRESS
: /* 1 */
1689 return SNMP_IPADDRESS(ifaddr
);
1691 case OSPFADDRESSLESSIF
: /* 2 */
1692 return SNMP_INTEGER(ifindex
);
1694 case OSPFIFAREAID
: /* 3 */
1696 return SNMP_IPADDRESS(oi
->area
->area_id
);
1698 return SNMP_IPADDRESS(ospf_empty_addr
);
1700 case OSPFIFTYPE
: /* 4 */
1701 return SNMP_INTEGER(ospf_snmp_iftype(oi
->ifp
));
1703 case OSPFIFADMINSTAT
: /* 5 */
1705 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1707 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1709 case OSPFIFRTRPRIORITY
: /* 6 */
1710 return SNMP_INTEGER(PRIORITY(oi
));
1712 case OSPFIFTRANSITDELAY
: /* 7 */
1713 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
1715 case OSPFIFRETRANSINTERVAL
: /* 8 */
1716 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
1718 case OSPFIFHELLOINTERVAL
: /* 9 */
1719 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
1721 case OSPFIFRTRDEADINTERVAL
: /* 10 */
1722 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
1724 case OSPFIFPOLLINTERVAL
: /* 11 */
1725 return SNMP_INTEGER(OSPF_POLL_INTERVAL_DEFAULT
);
1727 case OSPFIFSTATE
: /* 12 */
1728 return SNMP_INTEGER(ISM_SNMP(oi
->state
));
1730 case OSPFIFDESIGNATEDROUTER
: /* 13 */
1731 return SNMP_IPADDRESS(DR(oi
));
1733 case OSPFIFBACKUPDESIGNATEDROUTER
: /* 14 */
1734 return SNMP_IPADDRESS(BDR(oi
));
1736 case OSPFIFEVENTS
: /* 15 */
1737 return SNMP_INTEGER(oi
->state_change
);
1739 case OSPFIFAUTHKEY
: /* 16 */
1741 return (u_char
*)OSPF_IF_PARAM(oi
, auth_simple
);
1743 case OSPFIFSTATUS
: /* 17 */
1744 return SNMP_INTEGER(SNMP_VALID
);
1746 case OSPFIFMULTICASTFORWARDING
: /* 18 */
1748 /* clang-format off */
1749 #define ospf_snmp_multiforward_blocked 1
1750 #define ospf_snmp_multiforward_multicast 2
1751 #define ospf_snmp_multiforward_unicast 3
1752 return SNMP_INTEGER(ospf_snmp_multiforward_blocked
);
1754 case OSPFIFDEMAND
: /* 19 */
1755 return SNMP_INTEGER(SNMP_FALSE
);
1757 case OSPFIFAUTHTYPE
: /* 20 */
1759 return SNMP_INTEGER(oi
->area
->auth_type
);
1761 return SNMP_INTEGER(0);
1770 #define OSPF_SNMP_METRIC_VALUE 1
1772 static struct ospf_interface
*ospfIfMetricLookup(struct variable
*v
, oid
*name
,
1774 struct in_addr
*ifaddr
,
1775 ifindex_t
*ifindex
, int exact
)
1778 int ifaddr_next
= 0;
1779 ifindex_t ifindex_next
= 0;
1780 struct ospf_interface
*oi
;
1785 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1)
1788 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, ifaddr
);
1789 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1790 metric
= name
[v
->namelen
+ IN_ADDR_SIZE
+ 1];
1792 if (metric
!= OSPF_SNMP_METRIC_VALUE
)
1795 return ospf_snmp_if_lookup(ifaddr
, ifindex
);
1797 len
= *length
- v
->namelen
;
1798 if (len
>= IN_ADDR_SIZE
)
1803 oid2in_addr(name
+ v
->namelen
, len
, ifaddr
);
1805 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
1812 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
1814 oi
= ospf_snmp_if_lookup_next(ifaddr
, ifindex
, ifaddr_next
,
1817 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1 + 1;
1818 offset
= name
+ v
->namelen
;
1819 oid_copy_addr(offset
, ifaddr
, IN_ADDR_SIZE
);
1820 offset
+= IN_ADDR_SIZE
;
1823 *offset
= OSPF_SNMP_METRIC_VALUE
;
1830 static u_char
*ospfIfMetricEntry(struct variable
*v
, oid
*name
, size_t *length
,
1831 int exact
, size_t *var_len
,
1832 WriteMethod
**write_method
)
1834 /* Currently we support metric 1 only. */
1836 struct in_addr ifaddr
;
1837 struct ospf_interface
*oi
;
1840 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1845 memset(&ifaddr
, 0, sizeof(struct in_addr
));
1847 /* Check OSPF instance. */
1848 ospf
= ospf_lookup();
1852 oi
= ospfIfMetricLookup(v
, name
, length
, &ifaddr
, &ifindex
, exact
);
1856 /* Return the current value of the variable */
1858 case OSPFIFMETRICIPADDRESS
:
1859 return SNMP_IPADDRESS(ifaddr
);
1861 case OSPFIFMETRICADDRESSLESSIF
:
1862 return SNMP_INTEGER(ifindex
);
1864 case OSPFIFMETRICTOS
:
1865 return SNMP_INTEGER(0);
1867 case OSPFIFMETRICVALUE
:
1868 return SNMP_INTEGER(OSPF_SNMP_METRIC_VALUE
);
1870 case OSPFIFMETRICSTATUS
:
1871 return SNMP_INTEGER(1);
1880 static struct route_table
*ospf_snmp_vl_table
;
1882 static int ospf_snmp_vl_add(struct ospf_vl_data
*vl_data
)
1884 struct prefix_ls lp
;
1885 struct route_node
*rn
;
1887 memset(&lp
, 0, sizeof(struct prefix_ls
));
1890 lp
.id
= vl_data
->vl_area_id
;
1891 lp
.adv_router
= vl_data
->vl_peer
;
1893 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1895 route_unlock_node(rn
);
1901 static int ospf_snmp_vl_delete(struct ospf_vl_data
*vl_data
)
1903 struct prefix_ls lp
;
1904 struct route_node
*rn
;
1906 memset(&lp
, 0, sizeof(struct prefix_ls
));
1909 lp
.id
= vl_data
->vl_area_id
;
1910 lp
.adv_router
= vl_data
->vl_peer
;
1912 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1916 route_unlock_node(rn
);
1917 route_unlock_node(rn
);
1921 static struct ospf_vl_data
*ospf_snmp_vl_lookup(struct in_addr
*area_id
,
1922 struct in_addr
*neighbor
)
1924 struct prefix_ls lp
;
1925 struct route_node
*rn
;
1926 struct ospf_vl_data
*vl_data
;
1928 memset(&lp
, 0, sizeof(struct prefix_ls
));
1932 lp
.adv_router
= *neighbor
;
1934 rn
= route_node_lookup(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1937 route_unlock_node(rn
);
1943 static struct ospf_vl_data
*ospf_snmp_vl_lookup_next(struct in_addr
*area_id
,
1944 struct in_addr
*neighbor
,
1947 struct prefix_ls lp
;
1948 struct route_node
*rn
;
1949 struct ospf_vl_data
*vl_data
;
1951 memset(&lp
, 0, sizeof(struct prefix_ls
));
1955 lp
.adv_router
= *neighbor
;
1958 rn
= route_top(ospf_snmp_vl_table
);
1960 rn
= route_node_get(ospf_snmp_vl_table
, (struct prefix
*)&lp
);
1961 rn
= route_next(rn
);
1964 for (; rn
; rn
= route_next(rn
))
1968 if (rn
&& rn
->info
) {
1970 *area_id
= vl_data
->vl_area_id
;
1971 *neighbor
= vl_data
->vl_peer
;
1972 route_unlock_node(rn
);
1978 static struct ospf_vl_data
*
1979 ospfVirtIfLookup(struct variable
*v
, oid
*name
, size_t *length
,
1980 struct in_addr
*area_id
, struct in_addr
*neighbor
, int exact
)
1984 struct ospf_vl_data
*vl_data
;
1987 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
1990 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, area_id
);
1991 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, IN_ADDR_SIZE
,
1994 return ospf_snmp_vl_lookup(area_id
, neighbor
);
1998 len
= *length
- v
->namelen
;
2001 if (len
> IN_ADDR_SIZE
)
2003 oid2in_addr(name
+ v
->namelen
, len
, area_id
);
2005 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
2006 if (len
> IN_ADDR_SIZE
)
2008 oid2in_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
, len
, neighbor
);
2010 vl_data
= ospf_snmp_vl_lookup_next(area_id
, neighbor
, first
);
2013 *length
= v
->namelen
+ IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
2014 oid_copy_addr(name
+ v
->namelen
, area_id
, IN_ADDR_SIZE
);
2015 oid_copy_addr(name
+ v
->namelen
+ IN_ADDR_SIZE
,
2016 neighbor
, IN_ADDR_SIZE
);
2023 static u_char
*ospfVirtIfEntry(struct variable
*v
, oid
*name
, size_t *length
,
2024 int exact
, size_t *var_len
,
2025 WriteMethod
**write_method
)
2027 struct ospf_vl_data
*vl_data
;
2028 struct ospf_interface
*oi
;
2029 struct in_addr area_id
;
2030 struct in_addr neighbor
;
2032 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2036 memset(&area_id
, 0, sizeof(struct in_addr
));
2037 memset(&neighbor
, 0, sizeof(struct in_addr
));
2039 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
2042 oi
= vl_data
->vl_oi
;
2046 /* Return the current value of the variable */
2048 case OSPFVIRTIFAREAID
:
2049 return SNMP_IPADDRESS(area_id
);
2051 case OSPFVIRTIFNEIGHBOR
:
2052 return SNMP_IPADDRESS(neighbor
);
2054 case OSPFVIRTIFTRANSITDELAY
:
2055 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, transmit_delay
));
2057 case OSPFVIRTIFRETRANSINTERVAL
:
2058 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, retransmit_interval
));
2060 case OSPFVIRTIFHELLOINTERVAL
:
2061 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_hello
));
2063 case OSPFVIRTIFRTRDEADINTERVAL
:
2064 return SNMP_INTEGER(OSPF_IF_PARAM(oi
, v_wait
));
2066 case OSPFVIRTIFSTATE
:
2067 return SNMP_INTEGER(oi
->state
);
2069 case OSPFVIRTIFEVENTS
:
2070 return SNMP_INTEGER(oi
->state_change
);
2072 case OSPFVIRTIFAUTHKEY
:
2074 return (u_char
*)OSPF_IF_PARAM(oi
, auth_simple
);
2076 case OSPFVIRTIFSTATUS
:
2077 return SNMP_INTEGER(SNMP_VALID
);
2079 case OSPFVIRTIFAUTHTYPE
:
2081 return SNMP_INTEGER(oi
->area
->auth_type
);
2083 return SNMP_INTEGER(0);
2092 static struct ospf_neighbor
*ospf_snmp_nbr_lookup(struct ospf
*ospf
,
2093 struct in_addr
*nbr_addr
,
2096 struct listnode
*node
, *nnode
;
2097 struct ospf_interface
*oi
;
2098 struct ospf_neighbor
*nbr
;
2099 struct route_node
*rn
;
2101 for (ALL_LIST_ELEMENTS(ospf
->oiflist
, node
, nnode
, oi
)) {
2102 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2103 if ((nbr
= rn
->info
) != NULL
&& nbr
!= oi
->nbr_self
2104 /* If EXACT match is needed, provide ALL entry found
2105 && nbr->state != NSM_Down
2107 && nbr
->src
.s_addr
!= 0) {
2108 if (IPV4_ADDR_SAME(&nbr
->src
, nbr_addr
)) {
2109 route_unlock_node(rn
);
2117 static struct ospf_neighbor
*ospf_snmp_nbr_lookup_next(struct in_addr
*nbr_addr
,
2121 struct listnode
*nn
;
2122 struct ospf_interface
*oi
;
2123 struct ospf_neighbor
*nbr
;
2124 struct route_node
*rn
;
2125 struct ospf_neighbor
*min
= NULL
;
2126 struct ospf
*ospf
= ospf
;
2128 ospf
= ospf_lookup();
2130 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, nn
, oi
)) {
2131 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
2132 if ((nbr
= rn
->info
) != NULL
&& nbr
!= oi
->nbr_self
2133 && nbr
->state
!= NSM_Down
&& nbr
->src
.s_addr
!= 0) {
2137 else if (ntohl(nbr
->src
.s_addr
)
2138 < ntohl(min
->src
.s_addr
))
2140 } else if (ntohl(nbr
->src
.s_addr
)
2141 > ntohl(nbr_addr
->s_addr
)) {
2144 else if (ntohl(nbr
->src
.s_addr
)
2145 < ntohl(min
->src
.s_addr
))
2151 *nbr_addr
= min
->src
;
2158 static struct ospf_neighbor
*ospfNbrLookup(struct variable
*v
, oid
*name
,
2160 struct in_addr
*nbr_addr
,
2161 ifindex_t
*ifindex
, int exact
)
2165 struct ospf_neighbor
*nbr
;
2168 ospf
= ospf_lookup();
2174 if (*length
!= v
->namelen
+ IN_ADDR_SIZE
+ 1)
2177 oid2in_addr(name
+ v
->namelen
, IN_ADDR_SIZE
, nbr_addr
);
2178 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2180 return ospf_snmp_nbr_lookup(ospf
, nbr_addr
, ifindex
);
2183 len
= *length
- v
->namelen
;
2188 if (len
> IN_ADDR_SIZE
)
2191 oid2in_addr(name
+ v
->namelen
, len
, nbr_addr
);
2193 len
= *length
- v
->namelen
- IN_ADDR_SIZE
;
2195 *ifindex
= name
[v
->namelen
+ IN_ADDR_SIZE
];
2197 nbr
= ospf_snmp_nbr_lookup_next(nbr_addr
, ifindex
, first
);
2200 *length
= v
->namelen
+ IN_ADDR_SIZE
+ 1;
2201 oid_copy_addr(name
+ v
->namelen
, nbr_addr
,
2203 name
[v
->namelen
+ IN_ADDR_SIZE
] = *ifindex
;
2210 /* map internal quagga neighbor states to official MIB values:
2212 ospfNbrState OBJECT-TYPE
2224 static int32_t ospf_snmp_neighbor_state(u_char nst
)
2242 return 1; /* down */
2246 static u_char
*ospfNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2247 int exact
, size_t *var_len
,
2248 WriteMethod
**write_method
)
2250 struct in_addr nbr_addr
;
2252 struct ospf_neighbor
*nbr
;
2253 struct ospf_interface
*oi
;
2255 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2259 memset(&nbr_addr
, 0, sizeof(struct in_addr
));
2262 nbr
= ospfNbrLookup(v
, name
, length
, &nbr_addr
, &ifindex
, exact
);
2269 /* Return the current value of the variable */
2272 return SNMP_IPADDRESS(nbr_addr
);
2274 case OSPFNBRADDRESSLESSINDEX
:
2275 return SNMP_INTEGER(ifindex
);
2278 return SNMP_IPADDRESS(nbr
->router_id
);
2280 case OSPFNBROPTIONS
:
2281 return SNMP_INTEGER(oi
->nbr_self
->options
);
2283 case OSPFNBRPRIORITY
:
2284 return SNMP_INTEGER(nbr
->priority
);
2287 return SNMP_INTEGER(ospf_snmp_neighbor_state(nbr
->state
));
2290 return SNMP_INTEGER(nbr
->state_change
);
2292 case OSPFNBRLSRETRANSQLEN
:
2293 return SNMP_INTEGER(ospf_ls_retransmit_count(nbr
));
2295 case OSPFNBMANBRSTATUS
:
2296 return SNMP_INTEGER(SNMP_VALID
);
2298 case OSPFNBMANBRPERMANENCE
:
2299 return SNMP_INTEGER(2);
2301 case OSPFNBRHELLOSUPPRESSED
:
2302 return SNMP_INTEGER(SNMP_FALSE
);
2311 static u_char
*ospfVirtNbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
2312 int exact
, size_t *var_len
,
2313 WriteMethod
**write_method
)
2315 struct ospf_vl_data
*vl_data
;
2316 struct in_addr area_id
;
2317 struct in_addr neighbor
;
2320 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2324 memset(&area_id
, 0, sizeof(struct in_addr
));
2325 memset(&neighbor
, 0, sizeof(struct in_addr
));
2327 /* Check OSPF instance. */
2328 ospf
= ospf_lookup();
2332 vl_data
= ospfVirtIfLookup(v
, name
, length
, &area_id
, &neighbor
, exact
);
2336 /* Return the current value of the variable */
2338 case OSPFVIRTNBRAREA
:
2339 return (u_char
*)NULL
;
2341 case OSPFVIRTNBRRTRID
:
2342 return (u_char
*)NULL
;
2344 case OSPFVIRTNBRIPADDR
:
2345 return (u_char
*)NULL
;
2347 case OSPFVIRTNBROPTIONS
:
2348 return (u_char
*)NULL
;
2350 case OSPFVIRTNBRSTATE
:
2351 return (u_char
*)NULL
;
2353 case OSPFVIRTNBREVENTS
:
2354 return (u_char
*)NULL
;
2356 case OSPFVIRTNBRLSRETRANSQLEN
:
2357 return (u_char
*)NULL
;
2359 case OSPFVIRTNBRHELLOSUPPRESSED
:
2360 return (u_char
*)NULL
;
2369 static struct ospf_lsa
*ospfExtLsdbLookup(struct variable
*v
, oid
*name
,
2370 size_t *length
, u_char
*type
,
2371 struct in_addr
*ls_id
,
2372 struct in_addr
*router_id
, int exact
)
2379 struct ospf_lsa
*lsa
;
2382 ospf
= ospf_lookup();
2384 if (*length
!= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
)
2387 offset
= name
+ v
->namelen
;
2389 /* Make it sure given value match to type. */
2393 if (lsa_type
!= *type
)
2397 oid2in_addr(offset
, IN_ADDR_SIZE
, ls_id
);
2398 offset
+= IN_ADDR_SIZE
;
2401 oid2in_addr(offset
, IN_ADDR_SIZE
, router_id
);
2403 return ospf_lsdb_lookup_by_id(ospf
->lsdb
, *type
, *ls_id
,
2406 /* Get variable length. */
2408 offset
= name
+ v
->namelen
;
2409 offsetlen
= *length
- v
->namelen
;
2411 /* LSA type value. */
2416 if (offsetlen
<= 0 || lsa_type
< OSPF_AS_EXTERNAL_LSA
)
2421 if (len
> IN_ADDR_SIZE
)
2424 oid2in_addr(offset
, len
, ls_id
);
2426 offset
+= IN_ADDR_SIZE
;
2427 offsetlen
-= IN_ADDR_SIZE
;
2431 if (len
> IN_ADDR_SIZE
)
2434 oid2in_addr(offset
, len
, router_id
);
2436 lsa
= ospf_lsdb_lookup_by_id_next(ospf
->lsdb
, *type
, *ls_id
,
2440 /* Fill in length. */
2441 *length
= v
->namelen
+ 1 + IN_ADDR_SIZE
+ IN_ADDR_SIZE
;
2443 /* Fill in value. */
2444 offset
= name
+ v
->namelen
;
2446 *offset
= OSPF_AS_EXTERNAL_LSA
;
2448 oid_copy_addr(offset
, &lsa
->data
->id
, IN_ADDR_SIZE
);
2449 offset
+= IN_ADDR_SIZE
;
2450 oid_copy_addr(offset
, &lsa
->data
->adv_router
,
2459 static u_char
*ospfExtLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
2460 int exact
, size_t *var_len
,
2461 WriteMethod
**write_method
)
2463 struct ospf_lsa
*lsa
;
2464 struct lsa_header
*lsah
;
2466 struct in_addr ls_id
;
2467 struct in_addr router_id
;
2470 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2474 type
= OSPF_AS_EXTERNAL_LSA
;
2475 memset(&ls_id
, 0, sizeof(struct in_addr
));
2476 memset(&router_id
, 0, sizeof(struct in_addr
));
2478 /* Check OSPF instance. */
2479 ospf
= ospf_lookup();
2483 lsa
= ospfExtLsdbLookup(v
, name
, length
, &type
, &ls_id
, &router_id
,
2490 /* Return the current value of the variable */
2492 case OSPFEXTLSDBTYPE
:
2493 return SNMP_INTEGER(OSPF_AS_EXTERNAL_LSA
);
2495 case OSPFEXTLSDBLSID
:
2496 return SNMP_IPADDRESS(lsah
->id
);
2498 case OSPFEXTLSDBROUTERID
:
2499 return SNMP_IPADDRESS(lsah
->adv_router
);
2501 case OSPFEXTLSDBSEQUENCE
:
2502 return SNMP_INTEGER(lsah
->ls_seqnum
);
2504 case OSPFEXTLSDBAGE
:
2505 return SNMP_INTEGER(lsah
->ls_age
);
2507 case OSPFEXTLSDBCHECKSUM
:
2508 return SNMP_INTEGER(lsah
->checksum
);
2510 case OSPFEXTLSDBADVERTISEMENT
:
2511 *var_len
= ntohs(lsah
->length
);
2512 return (u_char
*)lsah
;
2521 static u_char
*ospfAreaAggregateEntry(struct variable
*v
, oid
*name
,
2522 size_t *length
, int exact
,
2524 WriteMethod
**write_method
)
2526 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
2530 /* Return the current value of the variable */
2532 case OSPFAREAAGGREGATEAREAID
:
2533 return (u_char
*)NULL
;
2535 case OSPFAREAAGGREGATELSDBTYPE
:
2536 return (u_char
*)NULL
;
2538 case OSPFAREAAGGREGATENET
:
2539 return (u_char
*)NULL
;
2541 case OSPFAREAAGGREGATEMASK
:
2542 return (u_char
*)NULL
;
2544 case OSPFAREAAGGREGATESTATUS
:
2545 return (u_char
*)NULL
;
2547 case OSPFAREAAGGREGATEEFFECT
:
2548 return (u_char
*)NULL
;
2558 #define IFSTATECHANGE 16
2559 #define VIRTIFSTATECHANGE 1
2560 #define NBRSTATECHANGE 2
2561 #define VIRTNBRSTATECHANGE 3
2563 static struct trap_object ospfNbrTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2564 {3, {10, 1, OSPFNBRIPADDR
}},
2565 {3, {10, 1, OSPFNBRRTRID
}},
2566 {3, {10, 1, OSPFNBRSTATE
}}};
2569 static struct trap_object ospfVirtNbrTrapList
[] = {
2571 {3, {11, 1, OSPFVIRTNBRAREA
}},
2572 {3, {11, 1, OSPFVIRTNBRRTRID
}},
2573 {3, {11, 1, OSPFVIRTNBRSTATE
}}};
2575 static struct trap_object ospfIfTrapList
[] = {{-2, {1, OSPFROUTERID
}},
2576 {3, {7, 1, OSPFIFIPADDRESS
}},
2577 {3, {7, 1, OSPFADDRESSLESSIF
}},
2578 {3, {7, 1, OSPFIFSTATE
}}};
2580 static struct trap_object ospfVirtIfTrapList
[] = {
2581 {-2, {1, OSPFROUTERID
}},
2582 {3, {9, 1, OSPFVIRTIFAREAID
}},
2583 {3, {9, 1, OSPFVIRTIFNEIGHBOR
}},
2584 {3, {9, 1, OSPFVIRTIFSTATE
}}};
2586 static void ospfTrapNbrStateChange(struct ospf_neighbor
*on
)
2588 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2591 ospf_nbr_state_message(on
, msgbuf
, sizeof(msgbuf
));
2592 zlog_info("ospfTrapNbrStateChange trap sent: %s now %s",
2593 inet_ntoa(on
->address
.u
.prefix4
), msgbuf
);
2595 oid_copy_addr(index
, &(on
->address
.u
.prefix4
), IN_ADDR_SIZE
);
2596 index
[IN_ADDR_SIZE
] = 0;
2598 smux_trap(ospf_variables
,
2599 sizeof ospf_variables
/ sizeof(struct variable
),
2600 ospf_trap_oid
, sizeof ospf_trap_oid
/ sizeof(oid
), ospf_oid
,
2601 sizeof ospf_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2603 sizeof ospfNbrTrapList
/ sizeof(struct trap_object
),
2607 static void ospfTrapVirtNbrStateChange(struct ospf_neighbor
*on
)
2609 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2611 zlog_info("ospfTrapVirtNbrStateChange trap sent");
2613 oid_copy_addr(index
, &(on
->address
.u
.prefix4
), IN_ADDR_SIZE
);
2614 index
[IN_ADDR_SIZE
] = 0;
2616 smux_trap(ospf_variables
,
2617 sizeof ospf_variables
/ sizeof(struct variable
),
2618 ospf_trap_oid
, sizeof ospf_trap_oid
/ sizeof(oid
), ospf_oid
,
2619 sizeof ospf_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2620 ospfVirtNbrTrapList
,
2621 sizeof ospfVirtNbrTrapList
/ sizeof(struct trap_object
),
2622 VIRTNBRSTATECHANGE
);
2625 static int ospf_snmp_nsm_change(struct ospf_neighbor
*nbr
, int next_state
,
2628 /* Terminal state or regression */
2629 if ((next_state
== NSM_Full
) || (next_state
== NSM_TwoWay
)
2630 || (next_state
< old_state
)) {
2631 /* ospfVirtNbrStateChange */
2632 if (nbr
->oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2633 ospfTrapVirtNbrStateChange(nbr
);
2634 /* ospfNbrStateChange trap */
2636 /* To/From FULL, only managed by DR */
2637 if (((next_state
!= NSM_Full
)
2638 && (nbr
->state
!= NSM_Full
))
2639 || (nbr
->oi
->state
== ISM_DR
))
2640 ospfTrapNbrStateChange(nbr
);
2645 static void ospfTrapIfStateChange(struct ospf_interface
*oi
)
2647 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2649 zlog_info("ospfTrapIfStateChange trap sent: %s now %s",
2650 inet_ntoa(oi
->address
->u
.prefix4
),
2651 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
2653 oid_copy_addr(index
, &(oi
->address
->u
.prefix4
), IN_ADDR_SIZE
);
2654 index
[IN_ADDR_SIZE
] = 0;
2656 smux_trap(ospf_variables
,
2657 sizeof ospf_variables
/ sizeof(struct variable
),
2658 ospf_trap_oid
, sizeof ospf_trap_oid
/ sizeof(oid
), ospf_oid
,
2659 sizeof ospf_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2661 sizeof ospfIfTrapList
/ sizeof(struct trap_object
),
2665 static void ospfTrapVirtIfStateChange(struct ospf_interface
*oi
)
2667 oid index
[sizeof(oid
) * (IN_ADDR_SIZE
+ 1)];
2669 zlog_info("ospfTrapVirtIfStateChange trap sent");
2671 oid_copy_addr(index
, &(oi
->address
->u
.prefix4
), IN_ADDR_SIZE
);
2672 index
[IN_ADDR_SIZE
] = 0;
2674 smux_trap(ospf_variables
,
2675 sizeof ospf_variables
/ sizeof(struct variable
),
2676 ospf_trap_oid
, sizeof ospf_trap_oid
/ sizeof(oid
), ospf_oid
,
2677 sizeof ospf_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
+ 1,
2679 sizeof ospfVirtIfTrapList
/ sizeof(struct trap_object
),
2683 static int ospf_snmp_ism_change(struct ospf_interface
*oi
, int state
,
2686 /* Terminal state or regression */
2687 if ((state
== ISM_DR
) || (state
== ISM_Backup
) || (state
== ISM_DROther
)
2688 || (state
== ISM_PointToPoint
) || (state
< old_state
)) {
2689 /* ospfVirtIfStateChange */
2690 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2691 ospfTrapVirtIfStateChange(oi
);
2692 /* ospfIfStateChange */
2694 ospfTrapIfStateChange(oi
);
2699 /* Register OSPF2-MIB. */
2700 static int ospf_snmp_init(struct thread_master
*tm
)
2702 ospf_snmp_iflist
= list_new();
2703 ospf_snmp_vl_table
= route_table_init();
2705 REGISTER_MIB("mibII/ospf", ospf_variables
, variable
, ospf_oid
);
2709 static int ospf_snmp_module_init(void)
2711 hook_register(ospf_if_update
, ospf_snmp_if_update
);
2712 hook_register(ospf_if_delete
, ospf_snmp_if_delete
);
2713 hook_register(ospf_vl_add
, ospf_snmp_vl_add
);
2714 hook_register(ospf_vl_delete
, ospf_snmp_vl_delete
);
2715 hook_register(ospf_ism_change
, ospf_snmp_ism_change
);
2716 hook_register(ospf_nsm_change
, ospf_snmp_nsm_change
);
2718 hook_register(frr_late_init
, ospf_snmp_init
);
2722 FRR_MODULE_SETUP(.name
= "ospfd_snmp", .version
= FRR_VERSION
,
2723 .description
= "ospfd AgentX SNMP module",
2724 .init
= ospf_snmp_module_init
, )