2 * Copyright (C) 2004 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <net-snmp/net-snmp-config.h>
24 #include <net-snmp/net-snmp-includes.h>
33 #include "lib/version.h"
35 #include "ospf6_proto.h"
36 #include "ospf6_lsa.h"
37 #include "ospf6_lsdb.h"
38 #include "ospf6_route.h"
39 #include "ospf6_top.h"
40 #include "ospf6_area.h"
41 #include "ospf6_interface.h"
42 #include "ospf6_message.h"
43 #include "ospf6_neighbor.h"
44 #include "ospf6_abr.h"
45 #include "ospf6_asbr.h"
49 #define OSPFv3MIB 1,3,6,1,2,1,191
51 /* OSPFv3 MIB General Group values. */
52 #define OSPFv3ROUTERID 1
53 #define OSPFv3ADMINSTAT 2
54 #define OSPFv3VERSIONNUMBER 3
55 #define OSPFv3AREABDRRTRSTATUS 4
56 #define OSPFv3ASBDRRTRSTATUS 5
57 #define OSPFv3ASSCOPELSACOUNT 6
58 #define OSPFv3ASSCOPELSACHECKSUMSUM 7
59 #define OSPFv3ORIGINATENEWLSAS 8
60 #define OSPFv3RXNEWLSAS 9
61 #define OSPFv3EXTLSACOUNT 10
62 #define OSPFv3EXTAREALSDBLIMIT 11
63 #define OSPFv3EXITOVERFLOWINTERVAL 12
64 #define OSPFv3DEMANDEXTENSIONS 13
65 #define OSPFv3REFERENCEBANDWIDTH 14
66 #define OSPFv3RESTARTSUPPORT 15
67 #define OSPFv3RESTARTINTERVAL 16
68 #define OSPFv3RESTARTSTRICTLSACHECKING 17
69 #define OSPFv3RESTARTSTATUS 18
70 #define OSPFv3RESTARTAGE 19
71 #define OSPFv3RESTARTEXITREASON 20
72 #define OSPFv3NOTIFICATIONENABLE 21
73 #define OSPFv3STUBROUTERSUPPORT 22
74 #define OSPFv3STUBROUTERADVERTISEMENT 23
75 #define OSPFv3DISCONTINUITYTIME 24
76 #define OSPFv3RESTARTTIME 25
78 /* OSPFv3 MIB Area Table values: ospfv3AreaTable */
79 #define OSPFv3IMPORTASEXTERN 2
80 #define OSPFv3AREASPFRUNS 3
81 #define OSPFv3AREABDRRTRCOUNT 4
82 #define OSPFv3AREAASBDRRTRCOUNT 5
83 #define OSPFv3AREASCOPELSACOUNT 6
84 #define OSPFv3AREASCOPELSACKSUMSUM 7
85 #define OSPFv3AREASUMMARY 8
86 #define OSPFv3AREAROWSTATUS 9
87 #define OSPFv3AREASTUBMETRIC 10
88 #define OSPFv3AREANSSATRANSLATORROLE 11
89 #define OSPFv3AREANSSATRANSLATORSTATE 12
90 #define OSPFv3AREANSSATRANSLATORSTABINTERVAL 13
91 #define OSPFv3AREANSSATRANSLATOREVENTS 14
92 #define OSPFv3AREASTUBMETRICTYPE 15
93 #define OSPFv3AREATEENABLED 16
95 /* OSPFv3 MIB * Lsdb Table values: ospfv3*LsdbTable */
96 #define OSPFv3WWLSDBSEQUENCE 1
97 #define OSPFv3WWLSDBAGE 2
98 #define OSPFv3WWLSDBCHECKSUM 3
99 #define OSPFv3WWLSDBADVERTISEMENT 4
100 #define OSPFv3WWLSDBTYPEKNOWN 5
102 /* Three first bits are to identify column */
103 #define OSPFv3WWCOLUMN 0x7
104 /* Then we use other bits to identify table */
105 #define OSPFv3WWASTABLE (1 << 3)
106 #define OSPFv3WWAREATABLE (1 << 4)
107 #define OSPFv3WWLINKTABLE (1 << 5)
108 #define OSPFv3WWVIRTLINKTABLE (1 << 6)
110 /* OSPFv3 MIB Host Table values: ospfv3HostTable */
111 #define OSPFv3HOSTMETRIC 3
112 #define OSPFv3HOSTROWSTATUS 4
113 #define OSPFv3HOSTAREAID 5
115 /* OSPFv3 MIB Interface Table values: ospfv3IfTable */
116 #define OSPFv3IFAREAID 3
117 #define OSPFv3IFTYPE 4
118 #define OSPFv3IFADMINSTATUS 5
119 #define OSPFv3IFRTRPRIORITY 6
120 #define OSPFv3IFTRANSITDELAY 7
121 #define OSPFv3IFRETRANSINTERVAL 8
122 #define OSPFv3IFHELLOINTERVAL 9
123 #define OSPFv3IFRTRDEADINTERVAL 10
124 #define OSPFv3IFPOLLINTERVAL 11
125 #define OSPFv3IFSTATE 12
126 #define OSPFv3IFDESIGNATEDROUTER 13
127 #define OSPFv3IFBACKUPDESIGNATEDROUTER 14
128 #define OSPFv3IFEVENTS 15
129 #define OSPFv3IFROWSTATUS 16
130 #define OSPFv3IFDEMAND 17
131 #define OSPFv3IFMETRICVALUE 18
132 #define OSPFv3IFLINKSCOPELSACOUNT 19
133 #define OSPFv3IFLINKLSACKSUMSUM 20
134 #define OSPFv3IFDEMANDNBRPROBE 21
135 #define OSPFv3IFDEMANDNBRPROBERETRANSLIMIT 22
136 #define OSPFv3IFDEMANDNBRPROBEINTERVAL 23
137 #define OSPFv3IFTEDISABLED 24
138 #define OSPFv3IFLINKLSASUPPRESSION 25
140 /* OSPFv3 MIB Virtual Interface Table values: ospfv3VirtIfTable */
141 #define OSPFv3VIRTIFINDEX 3
142 #define OSPFv3VIRTIFINSTID 4
143 #define OSPFv3VIRTIFTRANSITDELAY 5
144 #define OSPFv3VIRTIFRETRANSINTERVAL 6
145 #define OSPFv3VIRTIFHELLOINTERVAL 7
146 #define OSPFv3VIRTIFRTRDEADINTERVAL 8
147 #define OSPFv3VIRTIFSTATE 9
148 #define OSPFv3VIRTIFEVENTS 10
149 #define OSPFv3VIRTIFROWSTATUS 11
150 #define OSPFv3VIRTIFLINKSCOPELSACOUNT 12
151 #define OSPFv3VIRTIFLINKLSACKSUMSUM 13
153 /* OSPFv3 MIB Neighbors Table values: ospfv3NbrTable */
154 #define OSPFv3NBRADDRESSTYPE 4
155 #define OSPFv3NBRADDRESS 5
156 #define OSPFv3NBROPTIONS 6
157 #define OSPFv3NBRPRIORITY 7
158 #define OSPFv3NBRSTATE 8
159 #define OSPFv3NBREVENTS 9
160 #define OSPFv3NBRLSRETRANSQLEN 10
161 #define OSPFv3NBRHELLOSUPPRESSED 11
162 #define OSPFv3NBRIFID 12
163 #define OSPFv3NBRRESTARTHELPERSTATUS 13
164 #define OSPFv3NBRRESTARTHELPERAGE 14
165 #define OSPFv3NBRRESTARTHELPEREXITREASON 15
167 /* OSPFv3 MIB Configured Neighbors Table values: ospfv3CfgNbrTable */
168 #define OSPFv3CFGNBRPRIORITY 5
169 #define OSPFv3CFGNBRROWSTATUS 6
171 /* OSPFv3 MIB Virtual Neighbors Table values: ospfv3VirtNbrTable */
172 #define OSPFv3VIRTNBRIFINDEX 3
173 #define OSPFv3VIRTNBRIFINSTID 4
174 #define OSPFv3VIRTNBRADDRESSTYPE 5
175 #define OSPFv3VIRTNBRADDRESS 6
176 #define OSPFv3VIRTNBROPTIONS 7
177 #define OSPFv3VIRTNBRSTATE 8
178 #define OSPFv3VIRTNBREVENTS 9
179 #define OSPFv3VIRTNBRLSRETRANSQLEN 10
180 #define OSPFv3VIRTNBRHELLOSUPPRESSED 11
181 #define OSPFv3VIRTNBRIFID 12
182 #define OSPFv3VIRTNBRRESTARTHELPERSTATUS 13
183 #define OSPFv3VIRTNBRRESTARTHELPERAGE 14
184 #define OSPFv3VIRTNBRRESTARTHELPEREXITREASON 15
186 /* OSPFv3 MIB Area Aggregate Table values: ospfv3AreaAggregateTable */
187 #define OSPFv3AREAAGGREGATEROWSTATUS 6
188 #define OSPFv3AREAAGGREGATEEFFECT 7
189 #define OSPFv3AREAAGGREGATEROUTETAG 8
191 /* SYNTAX Status from OSPF-MIB. */
192 #define OSPF_STATUS_ENABLED 1
193 #define OSPF_STATUS_DISABLED 2
195 /* SNMP value hack. */
196 #define COUNTER ASN_COUNTER
197 #define INTEGER ASN_INTEGER
198 #define GAUGE ASN_GAUGE
199 #define UNSIGNED ASN_UNSIGNED
200 #define TIMETICKS ASN_TIMETICKS
201 #define IPADDRESS ASN_IPADDRESS
202 #define STRING ASN_OCTET_STR
204 /* For return values e.g. SNMP_INTEGER macro */
207 /* OSPFv3-MIB instances. */
208 static oid ospfv3_oid
[] = {OSPFv3MIB
};
209 static oid ospfv3_trap_oid
[] = {OSPFv3MIB
, 0};
211 /* Hook functions. */
212 static uint8_t *ospfv3GeneralGroup(struct variable
*, oid
*, size_t *, int,
213 size_t *, WriteMethod
**);
214 static uint8_t *ospfv3AreaEntry(struct variable
*, oid
*, size_t *, int,
215 size_t *, WriteMethod
**);
216 static uint8_t *ospfv3WwLsdbEntry(struct variable
*, oid
*, size_t *, int,
217 size_t *, WriteMethod
**);
218 static uint8_t *ospfv3NbrEntry(struct variable
*, oid
*, size_t *, int,
219 size_t *, WriteMethod
**);
220 static uint8_t *ospfv3IfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
223 static struct variable ospfv3_variables
[] = {
224 /* OSPF general variables */
225 {OSPFv3ROUTERID
, UNSIGNED
, RWRITE
, ospfv3GeneralGroup
, 3, {1, 1, 1}},
226 {OSPFv3ADMINSTAT
, INTEGER
, RWRITE
, ospfv3GeneralGroup
, 3, {1, 1, 2}},
227 {OSPFv3VERSIONNUMBER
, INTEGER
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 3}},
228 {OSPFv3AREABDRRTRSTATUS
,
234 {OSPFv3ASBDRRTRSTATUS
,
240 {OSPFv3ASSCOPELSACOUNT
, GAUGE
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 6}},
241 {OSPFv3ASSCOPELSACHECKSUMSUM
,
247 {OSPFv3ORIGINATENEWLSAS
,
253 {OSPFv3RXNEWLSAS
, COUNTER
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 9}},
254 {OSPFv3EXTLSACOUNT
, GAUGE
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 10}},
255 {OSPFv3EXTAREALSDBLIMIT
,
261 {OSPFv3EXITOVERFLOWINTERVAL
,
267 {OSPFv3DEMANDEXTENSIONS
,
273 {OSPFv3REFERENCEBANDWIDTH
,
279 {OSPFv3RESTARTSUPPORT
,
285 {OSPFv3RESTARTINTERVAL
,
291 {OSPFv3RESTARTSTRICTLSACHECKING
,
297 {OSPFv3RESTARTSTATUS
,
303 {OSPFv3RESTARTAGE
, UNSIGNED
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 19}},
304 {OSPFv3RESTARTEXITREASON
,
310 {OSPFv3NOTIFICATIONENABLE
,
316 {OSPFv3STUBROUTERSUPPORT
,
322 {OSPFv3STUBROUTERADVERTISEMENT
,
328 {OSPFv3DISCONTINUITYTIME
,
341 /* OSPFv3 Area Data Structure */
342 {OSPFv3IMPORTASEXTERN
,
348 {OSPFv3AREASPFRUNS
, COUNTER
, RONLY
, ospfv3AreaEntry
, 4, {1, 2, 1, 3}},
349 {OSPFv3AREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfv3AreaEntry
, 4, {1, 2, 1, 4}},
350 {OSPFv3AREAASBDRRTRCOUNT
,
356 {OSPFv3AREASCOPELSACOUNT
,
362 {OSPFv3AREASCOPELSACKSUMSUM
,
368 {OSPFv3AREASUMMARY
, INTEGER
, RWRITE
, ospfv3AreaEntry
, 4, {1, 2, 1, 8}},
369 {OSPFv3AREAROWSTATUS
,
375 {OSPFv3AREASTUBMETRIC
,
381 {OSPFv3AREANSSATRANSLATORROLE
,
387 {OSPFv3AREANSSATRANSLATORSTATE
,
393 {OSPFv3AREANSSATRANSLATORSTABINTERVAL
,
399 {OSPFv3AREANSSATRANSLATOREVENTS
,
405 {OSPFv3AREASTUBMETRICTYPE
,
411 {OSPFv3AREATEENABLED
,
419 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWASTABLE
,
425 {OSPFv3WWLSDBAGE
| OSPFv3WWASTABLE
,
431 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWASTABLE
,
437 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWASTABLE
,
443 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWASTABLE
,
450 /* OSPFv3 Area LSDB */
451 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWAREATABLE
,
457 {OSPFv3WWLSDBAGE
| OSPFv3WWAREATABLE
,
463 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWAREATABLE
,
469 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWAREATABLE
,
475 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWAREATABLE
,
482 /* OSPFv3 Link LSDB */
483 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWLINKTABLE
,
489 {OSPFv3WWLSDBAGE
| OSPFv3WWLINKTABLE
,
495 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWLINKTABLE
,
501 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWLINKTABLE
,
507 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWLINKTABLE
,
514 /* OSPFv3 interfaces */
515 {OSPFv3IFAREAID
, UNSIGNED
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 3}},
516 {OSPFv3IFTYPE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 4}},
517 {OSPFv3IFADMINSTATUS
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 5}},
518 {OSPFv3IFRTRPRIORITY
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 6}},
519 {OSPFv3IFTRANSITDELAY
, UNSIGNED
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 7}},
520 {OSPFv3IFRETRANSINTERVAL
,
526 {OSPFv3IFHELLOINTERVAL
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 9}},
527 {OSPFv3IFRTRDEADINTERVAL
,
533 {OSPFv3IFPOLLINTERVAL
,
539 {OSPFv3IFSTATE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 12}},
540 {OSPFv3IFDESIGNATEDROUTER
,
546 {OSPFv3IFBACKUPDESIGNATEDROUTER
,
552 {OSPFv3IFEVENTS
, COUNTER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 15}},
553 {OSPFv3IFROWSTATUS
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 16}},
554 {OSPFv3IFDEMAND
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 17}},
555 {OSPFv3IFMETRICVALUE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 18}},
556 {OSPFv3IFLINKSCOPELSACOUNT
,
562 {OSPFv3IFLINKLSACKSUMSUM
,
568 {OSPFv3IFDEMANDNBRPROBE
,
574 {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT
,
580 {OSPFv3IFDEMANDNBRPROBEINTERVAL
,
586 {OSPFv3IFTEDISABLED
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 24}},
587 {OSPFv3IFLINKLSASUPPRESSION
,
594 /* OSPFv3 neighbors */
595 {OSPFv3NBRADDRESSTYPE
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 4}},
596 {OSPFv3NBRADDRESS
, STRING
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 5}},
597 {OSPFv3NBROPTIONS
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 6}},
598 {OSPFv3NBRPRIORITY
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 7}},
599 {OSPFv3NBRSTATE
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 8}},
600 {OSPFv3NBREVENTS
, COUNTER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 9}},
601 {OSPFv3NBRLSRETRANSQLEN
,
607 {OSPFv3NBRHELLOSUPPRESSED
,
613 {OSPFv3NBRIFID
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 12}},
614 {OSPFv3NBRRESTARTHELPERSTATUS
,
620 {OSPFv3NBRRESTARTHELPERAGE
,
626 {OSPFv3NBRRESTARTHELPEREXITREASON
,
634 static uint8_t *ospfv3GeneralGroup(struct variable
*v
, oid
*name
,
635 size_t *length
, int exact
, size_t *var_len
,
636 WriteMethod
**write_method
)
640 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
643 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
644 /* Check whether the instance identifier is valid */
645 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
649 /* Return the current value of the variable */
652 /* Router-ID of this OSPF instance. */
654 return SNMP_INTEGER(ntohl(ospf6
->router_id
));
655 return SNMP_INTEGER(0);
656 case OSPFv3ADMINSTAT
:
659 CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
)
660 ? OSPF_STATUS_DISABLED
661 : OSPF_STATUS_ENABLED
);
662 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
663 case OSPFv3VERSIONNUMBER
:
664 return SNMP_INTEGER(3);
665 case OSPFv3AREABDRRTRSTATUS
:
668 ospf6_check_and_set_router_abr(ospf6
)
671 return SNMP_INTEGER(SNMP_FALSE
);
672 case OSPFv3ASBDRRTRSTATUS
:
674 return SNMP_INTEGER(ospf6_asbr_is_asbr(ospf6
)
677 return SNMP_INTEGER(SNMP_FALSE
);
678 case OSPFv3ASSCOPELSACOUNT
:
680 return SNMP_INTEGER(ospf6
->lsdb
->count
);
681 return SNMP_INTEGER(0);
682 case OSPFv3ASSCOPELSACHECKSUMSUM
:
685 for (ALL_LSDB(ospf6
->lsdb
, lsa
, lsanext
))
686 sum
+= ntohs(lsa
->header
->checksum
);
687 return SNMP_INTEGER(sum
);
689 return SNMP_INTEGER(0);
690 case OSPFv3ORIGINATENEWLSAS
:
692 0); /* Don't know where to get this value... */
693 case OSPFv3RXNEWLSAS
:
695 0); /* Don't know where to get this value... */
696 case OSPFv3EXTLSACOUNT
:
699 for (ALL_LSDB_TYPED(ospf6
->lsdb
,
700 htons(OSPF6_LSTYPE_AS_EXTERNAL
),
703 return SNMP_INTEGER(count
);
705 return SNMP_INTEGER(0);
706 case OSPFv3EXTAREALSDBLIMIT
:
707 return SNMP_INTEGER(-1);
708 case OSPFv3EXITOVERFLOWINTERVAL
:
709 return SNMP_INTEGER(0); /* Not supported */
710 case OSPFv3DEMANDEXTENSIONS
:
711 return SNMP_INTEGER(0); /* Not supported */
712 case OSPFv3REFERENCEBANDWIDTH
:
714 return SNMP_INTEGER(ospf6
->ref_bandwidth
);
715 /* Otherwise, like for "not implemented". */
717 case OSPFv3RESTARTSUPPORT
:
718 case OSPFv3RESTARTINTERVAL
:
719 case OSPFv3RESTARTSTRICTLSACHECKING
:
720 case OSPFv3RESTARTSTATUS
:
721 case OSPFv3RESTARTAGE
:
722 case OSPFv3RESTARTEXITREASON
:
723 case OSPFv3NOTIFICATIONENABLE
:
724 case OSPFv3STUBROUTERSUPPORT
:
725 case OSPFv3STUBROUTERADVERTISEMENT
:
726 case OSPFv3DISCONTINUITYTIME
:
727 case OSPFv3RESTARTTIME
:
728 /* TODO: Not implemented */
734 static uint8_t *ospfv3AreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
735 int exact
, size_t *var_len
,
736 WriteMethod
**write_method
)
738 struct ospf6_area
*oa
, *area
= NULL
;
739 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
740 uint32_t area_id
= 0;
743 struct listnode
*node
;
746 struct ospf6_route
*ro
;
749 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
754 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
758 len
= *length
- v
->namelen
;
759 len
= (len
>= 1 ? 1 : 0);
760 if (exact
&& len
!= 1)
763 area_id
= htonl(name
[v
->namelen
]);
765 inet_ntop(AF_INET
, &area_id
, a
, sizeof(a
));
766 zlog_debug("SNMP access by area: %s, exact=%d len=%d length=%lu", a
,
767 exact
, len
, (unsigned long)*length
);
769 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
771 if (len
== 0) /* return first area entry */
773 else if (exact
&& ntohl(oa
->area_id
) == ntohl(area_id
))
775 else if (ntohl(oa
->area_id
) > ntohl(area_id
))
783 *length
= v
->namelen
+ 1;
784 name
[v
->namelen
] = ntohl(area
->area_id
);
786 inet_ntop(AF_INET
, &area
->area_id
, a
, sizeof(a
));
787 zlog_debug("SNMP found area: %s, exact=%d len=%d length=%lu", a
, exact
,
788 len
, (unsigned long)*length
);
791 case OSPFv3IMPORTASEXTERN
:
792 /* No NSSA support */
793 return SNMP_INTEGER(IS_AREA_STUB(area
) ? 2 : 1);
794 case OSPFv3AREASPFRUNS
:
795 return SNMP_INTEGER(area
->spf_calculation
);
796 case OSPFv3AREABDRRTRCOUNT
:
797 case OSPFv3AREAASBDRRTRCOUNT
:
799 for (ro
= ospf6_route_head(ospf6
->brouter_table
); ro
;
800 ro
= ospf6_route_next(ro
)) {
801 if (ntohl(ro
->path
.area_id
) != ntohl(area
->area_id
))
803 if (v
->magic
== OSPFv3AREABDRRTRCOUNT
804 && CHECK_FLAG(ro
->path
.router_bits
,
807 if (v
->magic
== OSPFv3AREAASBDRRTRCOUNT
808 && CHECK_FLAG(ro
->path
.router_bits
,
812 return SNMP_INTEGER(count
);
813 case OSPFv3AREASCOPELSACOUNT
:
814 return SNMP_INTEGER(area
->lsdb
->count
);
815 case OSPFv3AREASCOPELSACKSUMSUM
:
817 for (ALL_LSDB(area
->lsdb
, lsa
, lsanext
))
818 sum
+= ntohs(lsa
->header
->checksum
);
819 return SNMP_INTEGER(sum
);
820 case OSPFv3AREASUMMARY
:
821 return SNMP_INTEGER(2); /* sendAreaSummary */
822 case OSPFv3AREAROWSTATUS
:
823 return SNMP_INTEGER(1); /* Active */
824 case OSPFv3AREASTUBMETRIC
:
825 case OSPFv3AREANSSATRANSLATORROLE
:
826 case OSPFv3AREANSSATRANSLATORSTATE
:
827 case OSPFv3AREANSSATRANSLATORSTABINTERVAL
:
828 case OSPFv3AREANSSATRANSLATOREVENTS
:
829 case OSPFv3AREASTUBMETRICTYPE
:
830 case OSPFv3AREATEENABLED
:
831 /* Not implemented. */
837 static int if_icmp_func(struct interface
*ifp1
, struct interface
*ifp2
)
839 return (ifp1
->ifindex
- ifp2
->ifindex
);
842 static uint8_t *ospfv3WwLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
843 int exact
, size_t *var_len
,
844 WriteMethod
**write_method
)
847 struct ospf6_lsa
*lsa
= NULL
;
849 uint32_t area_id
, id
, instid
, adv_router
;
854 struct ospf6_area
*oa
= NULL
;
855 struct listnode
*node
;
856 struct interface
*iif
;
857 struct ospf6_interface
*oi
= NULL
;
858 struct list
*ifslist
;
861 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
863 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
867 instid
= ifindex
= area_id
= type
= id
= adv_router
= 0;
869 /* Check OSPFv3 instance. */
873 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
874 /* Get variable length. */
875 offset
= name
+ v
->namelen
;
876 offsetlen
= *length
- v
->namelen
;
878 if (exact
&& (v
->magic
& OSPFv3WWASTABLE
) && offsetlen
!= 3)
880 if (exact
&& (v
->magic
& OSPFv3WWAREATABLE
) && offsetlen
!= 4)
882 if (exact
&& (v
->magic
& OSPFv3WWLINKTABLE
) && offsetlen
!= 5)
885 if (v
->magic
& OSPFv3WWLINKTABLE
) {
887 len
= (offsetlen
< 1 ? 0 : 1);
893 /* Parse instance ID */
894 len
= (offsetlen
< 1 ? 0 : 1);
899 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
901 len
= (offsetlen
< 1 ? 0 : 1);
903 area_id
= htonl(*offset
);
909 len
= (offsetlen
< 1 ? 0 : 1);
911 type
= htons(*offset
);
915 /* Parse Router-ID */
916 len
= (offsetlen
< 1 ? 0 : 1);
918 adv_router
= htonl(*offset
);
923 len
= (offsetlen
< 1 ? 0 : 1);
927 // offsetlen -= len; // Add back in if we need it again
930 if (v
->magic
& OSPFv3WWASTABLE
) {
931 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
,
933 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
934 oa
= ospf6_area_lookup(area_id
, ospf6
);
937 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, oa
->lsdb
);
938 } else if (v
->magic
& OSPFv3WWLINKTABLE
) {
939 oi
= ospf6_interface_lookup_by_ifindex(ifindex
,
941 if (!oi
|| oi
->instance_id
!= instid
)
943 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, oi
->lsdb
);
946 if (v
->magic
& OSPFv3WWASTABLE
) {
947 if (ospf6
->lsdb
->count
)
948 lsa
= ospf6_lsdb_lookup_next(
949 type
, id
, adv_router
, ospf6
->lsdb
);
950 } else if (v
->magic
& OSPFv3WWAREATABLE
)
951 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
952 if (oa
->area_id
< area_id
)
956 lsa
= ospf6_lsdb_lookup_next(
957 type
, id
, adv_router
, oa
->lsdb
);
964 else if (v
->magic
& OSPFv3WWLINKTABLE
) {
965 /* We build a sorted list of interfaces */
966 ifslist
= list_new();
967 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
968 FOR_ALL_INTERFACES (vrf
, iif
)
969 listnode_add_sort(ifslist
, iif
);
971 for (ALL_LIST_ELEMENTS_RO(ifslist
, node
, iif
)) {
974 oi
= ospf6_interface_lookup_by_ifindex(
975 iif
->ifindex
, iif
->vrf_id
);
978 if (iif
->ifindex
< ifindex
)
980 if (oi
->instance_id
< instid
)
984 lsa
= ospf6_lsdb_lookup_next(
985 type
, id
, adv_router
, oi
->lsdb
);
994 list_delete_all_node(ifslist
);
995 list_delete(&ifslist
);
1003 if (v
->magic
& OSPFv3WWASTABLE
) {
1004 *length
= v
->namelen
+ 3;
1005 offset
= name
+ v
->namelen
;
1006 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
1007 *length
= v
->namelen
+ 4;
1008 offset
= name
+ v
->namelen
;
1009 *offset
= ntohl(oa
->area_id
);
1011 } else if (v
->magic
& OSPFv3WWLINKTABLE
) {
1012 *length
= v
->namelen
+ 5;
1013 offset
= name
+ v
->namelen
;
1014 *offset
= oi
->interface
->ifindex
;
1016 *offset
= oi
->instance_id
;
1019 *offset
= ntohs(lsa
->header
->type
);
1021 *offset
= ntohl(lsa
->header
->adv_router
);
1023 *offset
= ntohl(lsa
->header
->id
);
1026 /* Return the current value of the variable */
1027 switch (v
->magic
& OSPFv3WWCOLUMN
) {
1028 case OSPFv3WWLSDBSEQUENCE
:
1029 return SNMP_INTEGER(ntohl(lsa
->header
->seqnum
));
1030 case OSPFv3WWLSDBAGE
:
1031 ospf6_lsa_age_current(lsa
);
1032 return SNMP_INTEGER(ntohs(lsa
->header
->age
));
1033 case OSPFv3WWLSDBCHECKSUM
:
1034 return SNMP_INTEGER(ntohs(lsa
->header
->checksum
));
1035 case OSPFv3WWLSDBADVERTISEMENT
:
1036 *var_len
= ntohs(lsa
->header
->length
);
1037 return (uint8_t *)lsa
->header
;
1038 case OSPFv3WWLSDBTYPEKNOWN
:
1039 return SNMP_INTEGER(OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
1047 static uint8_t *ospfv3IfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1048 int exact
, size_t *var_len
,
1049 WriteMethod
**write_method
)
1052 ifindex_t ifindex
= 0;
1053 unsigned int instid
= 0;
1054 struct ospf6_interface
*oi
= NULL
;
1055 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
1056 struct interface
*iif
;
1058 struct list
*ifslist
;
1062 struct ospf6
*ospf6
;
1064 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
1066 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1070 /* Check OSPFv3 instance. */
1074 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1075 /* Get variable length. */
1076 offset
= name
+ v
->namelen
;
1077 offsetlen
= *length
- v
->namelen
;
1079 if (exact
&& offsetlen
!= 2)
1082 /* Parse if index */
1083 len
= (offsetlen
< 1 ? 0 : 1);
1089 /* Parse instance ID */
1090 len
= (offsetlen
< 1 ? 0 : 1);
1093 // offset += len; // Add back in if we ever start using again
1094 // offsetlen -= len;
1097 oi
= ospf6_interface_lookup_by_ifindex(ifindex
, ospf6
->vrf_id
);
1098 if (!oi
|| oi
->instance_id
!= instid
)
1101 /* We build a sorted list of interfaces */
1102 ifslist
= list_new();
1103 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
1104 FOR_ALL_INTERFACES (vrf
, iif
)
1105 listnode_add_sort(ifslist
, iif
);
1107 for (ALL_LIST_ELEMENTS_RO(ifslist
, i
, iif
)) {
1110 oi
= ospf6_interface_lookup_by_ifindex(iif
->ifindex
,
1114 if (iif
->ifindex
> ifindex
1115 || (iif
->ifindex
== ifindex
1116 && (oi
->instance_id
> instid
)))
1121 list_delete_all_node(ifslist
);
1122 list_delete(&ifslist
);
1128 /* Add Index (IfIndex, IfInstId) */
1129 *length
= v
->namelen
+ 2;
1130 offset
= name
+ v
->namelen
;
1131 *offset
= oi
->interface
->ifindex
;
1133 *offset
= oi
->instance_id
;
1136 /* Return the current value of the variable */
1138 case OSPFv3IFAREAID
:
1140 return SNMP_INTEGER(ntohl(oi
->area
->area_id
));
1143 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1144 return SNMP_INTEGER(1);
1145 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1146 return SNMP_INTEGER(3);
1148 break; /* Unknown, don't put anything */
1149 case OSPFv3IFADMINSTATUS
:
1151 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1152 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1153 case OSPFv3IFRTRPRIORITY
:
1154 return SNMP_INTEGER(oi
->priority
);
1155 case OSPFv3IFTRANSITDELAY
:
1156 return SNMP_INTEGER(oi
->transdelay
);
1157 case OSPFv3IFRETRANSINTERVAL
:
1158 return SNMP_INTEGER(oi
->rxmt_interval
);
1159 case OSPFv3IFHELLOINTERVAL
:
1160 return SNMP_INTEGER(oi
->hello_interval
);
1161 case OSPFv3IFRTRDEADINTERVAL
:
1162 return SNMP_INTEGER(oi
->dead_interval
);
1163 case OSPFv3IFPOLLINTERVAL
:
1164 /* No support for NBMA */
1167 return SNMP_INTEGER(oi
->state
);
1168 case OSPFv3IFDESIGNATEDROUTER
:
1169 return SNMP_INTEGER(ntohl(oi
->drouter
));
1170 case OSPFv3IFBACKUPDESIGNATEDROUTER
:
1171 return SNMP_INTEGER(ntohl(oi
->bdrouter
));
1172 case OSPFv3IFEVENTS
:
1173 return SNMP_INTEGER(oi
->state_change
);
1174 case OSPFv3IFROWSTATUS
:
1175 return SNMP_INTEGER(1);
1176 case OSPFv3IFDEMAND
:
1177 return SNMP_INTEGER(SNMP_FALSE
);
1178 case OSPFv3IFMETRICVALUE
:
1179 return SNMP_INTEGER(oi
->cost
);
1180 case OSPFv3IFLINKSCOPELSACOUNT
:
1181 return SNMP_INTEGER(oi
->lsdb
->count
);
1182 case OSPFv3IFLINKLSACKSUMSUM
:
1184 for (ALL_LSDB(oi
->lsdb
, lsa
, lsanext
))
1185 sum
+= ntohs(lsa
->header
->checksum
);
1186 return SNMP_INTEGER(sum
);
1187 case OSPFv3IFDEMANDNBRPROBE
:
1188 case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT
:
1189 case OSPFv3IFDEMANDNBRPROBEINTERVAL
:
1190 case OSPFv3IFTEDISABLED
:
1191 case OSPFv3IFLINKLSASUPPRESSION
:
1192 /* Not implemented. Only works if all the last ones are not
1197 /* Try an internal getnext. Some columns are missing in this table. */
1198 if (!exact
&& (name
[*length
- 1] < MAX_SUBID
))
1199 return ospfv3IfEntry(v
, name
, length
, exact
, var_len
,
1204 static uint8_t *ospfv3NbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
1205 int exact
, size_t *var_len
,
1206 WriteMethod
**write_method
)
1209 ifindex_t ifindex
= 0;
1210 unsigned int instid
, rtrid
;
1211 struct ospf6_interface
*oi
= NULL
;
1212 struct ospf6_neighbor
*on
= NULL
;
1213 struct interface
*iif
;
1214 struct listnode
*i
, *j
;
1215 struct list
*ifslist
;
1218 struct ospf6
*ospf6
;
1220 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
1222 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1228 /* Check OSPFv3 instance. */
1232 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1233 /* Get variable length. */
1234 offset
= name
+ v
->namelen
;
1235 offsetlen
= *length
- v
->namelen
;
1237 if (exact
&& offsetlen
!= 3)
1240 /* Parse if index */
1241 len
= (offsetlen
< 1 ? 0 : 1);
1247 /* Parse instance ID */
1248 len
= (offsetlen
< 1 ? 0 : 1);
1254 /* Parse router ID */
1255 len
= (offsetlen
< 1 ? 0 : 1);
1257 rtrid
= htonl(*offset
);
1258 // offset += len; // Add back in if we ever start looking at data
1259 // offsetlen -= len;
1262 oi
= ospf6_interface_lookup_by_ifindex(ifindex
, ospf6
->vrf_id
);
1263 if (!oi
|| oi
->instance_id
!= instid
)
1265 on
= ospf6_neighbor_lookup(rtrid
, oi
);
1267 /* We build a sorted list of interfaces */
1268 ifslist
= list_new();
1269 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
1270 FOR_ALL_INTERFACES (vrf
, iif
)
1271 listnode_add_sort(ifslist
, iif
);
1273 for (ALL_LIST_ELEMENTS_RO(ifslist
, i
, iif
)) {
1276 oi
= ospf6_interface_lookup_by_ifindex(iif
->ifindex
,
1280 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, j
, on
)) {
1281 if (iif
->ifindex
> ifindex
1282 || (iif
->ifindex
== ifindex
1283 && (oi
->instance_id
> instid
1284 || (oi
->instance_id
== instid
1285 && ntohl(on
->router_id
)
1295 list_delete_all_node(ifslist
);
1296 list_delete(&ifslist
);
1302 /* Add Index (IfIndex, IfInstId, RtrId) */
1303 *length
= v
->namelen
+ 3;
1304 offset
= name
+ v
->namelen
;
1305 *offset
= oi
->interface
->ifindex
;
1307 *offset
= oi
->instance_id
;
1309 *offset
= ntohl(on
->router_id
);
1312 /* Return the current value of the variable */
1314 case OSPFv3NBRADDRESSTYPE
:
1315 return SNMP_INTEGER(2); /* IPv6 only */
1316 case OSPFv3NBRADDRESS
:
1317 *var_len
= sizeof(struct in6_addr
);
1318 return (uint8_t *)&on
->linklocal_addr
;
1319 case OSPFv3NBROPTIONS
:
1320 return SNMP_INTEGER(on
->options
[2]);
1321 case OSPFv3NBRPRIORITY
:
1322 return SNMP_INTEGER(on
->priority
);
1323 case OSPFv3NBRSTATE
:
1324 return SNMP_INTEGER(on
->state
);
1325 case OSPFv3NBREVENTS
:
1326 return SNMP_INTEGER(on
->state_change
);
1327 case OSPFv3NBRLSRETRANSQLEN
:
1328 return SNMP_INTEGER(on
->retrans_list
->count
);
1329 case OSPFv3NBRHELLOSUPPRESSED
:
1330 return SNMP_INTEGER(SNMP_FALSE
);
1332 return SNMP_INTEGER(on
->ifindex
);
1333 case OSPFv3NBRRESTARTHELPERSTATUS
:
1334 case OSPFv3NBRRESTARTHELPERAGE
:
1335 case OSPFv3NBRRESTARTHELPEREXITREASON
:
1336 /* Not implemented. Only works if all the last ones are not
1345 #define NBRSTATECHANGE 2
1346 #define IFSTATECHANGE 10
1348 static struct trap_object ospf6NbrTrapList
[] = {
1349 {-3, {1, 1, OSPFv3ROUTERID
}},
1350 {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE
}},
1351 {4, {1, 9, 1, OSPFv3NBRADDRESS
}},
1352 {4, {1, 9, 1, OSPFv3NBRSTATE
}}};
1354 static struct trap_object ospf6IfTrapList
[] = {
1355 {-3, {1, 1, OSPFv3ROUTERID
}},
1356 {4, {1, 7, 1, OSPFv3IFSTATE
}},
1357 {4, {1, 7, 1, OSPFv3IFADMINSTATUS
}},
1358 {4, {1, 7, 1, OSPFv3IFAREAID
}}};
1360 static int ospf6TrapNbrStateChange(struct ospf6_neighbor
*on
, int next_state
,
1365 /* Terminal state or regression */
1366 if ((next_state
!= OSPF6_NEIGHBOR_FULL
)
1367 && (next_state
!= OSPF6_NEIGHBOR_TWOWAY
)
1368 && (next_state
>= prev_state
))
1371 index
[0] = on
->ospf6_if
->interface
->ifindex
;
1372 index
[1] = on
->ospf6_if
->instance_id
;
1373 index
[2] = ntohl(on
->router_id
);
1375 smux_trap(ospfv3_variables
, array_size(ospfv3_variables
),
1376 ospfv3_trap_oid
, array_size(ospfv3_trap_oid
), ospfv3_oid
,
1377 sizeof(ospfv3_oid
) / sizeof(oid
), index
, 3, ospf6NbrTrapList
,
1378 array_size(ospf6NbrTrapList
), NBRSTATECHANGE
);
1382 static int ospf6TrapIfStateChange(struct ospf6_interface
*oi
, int next_state
,
1387 /* Terminal state or regression */
1388 if ((next_state
!= OSPF6_INTERFACE_POINTTOPOINT
)
1389 && (next_state
!= OSPF6_INTERFACE_DROTHER
)
1390 && (next_state
!= OSPF6_INTERFACE_BDR
)
1391 && (next_state
!= OSPF6_INTERFACE_DR
) && (next_state
>= prev_state
))
1394 index
[0] = oi
->interface
->ifindex
;
1395 index
[1] = oi
->instance_id
;
1397 smux_trap(ospfv3_variables
, array_size(ospfv3_variables
),
1398 ospfv3_trap_oid
, array_size(ospfv3_trap_oid
), ospfv3_oid
,
1399 sizeof(ospfv3_oid
) / sizeof(oid
), index
, 2, ospf6IfTrapList
,
1400 array_size(ospf6IfTrapList
), IFSTATECHANGE
);
1404 /* Register OSPFv3-MIB. */
1405 static int ospf6_snmp_init(struct thread_master
*master
)
1408 REGISTER_MIB("OSPFv3MIB", ospfv3_variables
, variable
, ospfv3_oid
);
1412 static int ospf6_snmp_module_init(void)
1414 hook_register(ospf6_interface_change
, ospf6TrapIfStateChange
);
1415 hook_register(ospf6_neighbor_change
, ospf6TrapNbrStateChange
);
1416 hook_register(frr_late_init
, ospf6_snmp_init
);
1420 FRR_MODULE_SETUP(.name
= "ospf6d_snmp", .version
= FRR_VERSION
,
1421 .description
= "ospf6d AgentX SNMP module",
1422 .init
= ospf6_snmp_module_init
,