1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2004 Yasuhiro Ohara
8 #include <net-snmp/net-snmp-config.h>
9 #include <net-snmp/net-snmp-includes.h>
18 #include "lib/version.h"
20 #include "ospf6_proto.h"
21 #include "ospf6_lsa.h"
22 #include "ospf6_lsdb.h"
23 #include "ospf6_route.h"
24 #include "ospf6_top.h"
25 #include "ospf6_area.h"
26 #include "ospf6_interface.h"
27 #include "ospf6_message.h"
28 #include "ospf6_neighbor.h"
29 #include "ospf6_abr.h"
30 #include "ospf6_asbr.h"
34 #define OSPFv3MIB 1,3,6,1,2,1,191
36 /* OSPFv3 MIB General Group values. */
37 #define OSPFv3ROUTERID 1
38 #define OSPFv3ADMINSTAT 2
39 #define OSPFv3VERSIONNUMBER 3
40 #define OSPFv3AREABDRRTRSTATUS 4
41 #define OSPFv3ASBDRRTRSTATUS 5
42 #define OSPFv3ASSCOPELSACOUNT 6
43 #define OSPFv3ASSCOPELSACHECKSUMSUM 7
44 #define OSPFv3ORIGINATENEWLSAS 8
45 #define OSPFv3RXNEWLSAS 9
46 #define OSPFv3EXTLSACOUNT 10
47 #define OSPFv3EXTAREALSDBLIMIT 11
48 #define OSPFv3EXITOVERFLOWINTERVAL 12
49 #define OSPFv3DEMANDEXTENSIONS 13
50 #define OSPFv3REFERENCEBANDWIDTH 14
51 #define OSPFv3RESTARTSUPPORT 15
52 #define OSPFv3RESTARTINTERVAL 16
53 #define OSPFv3RESTARTSTRICTLSACHECKING 17
54 #define OSPFv3RESTARTSTATUS 18
55 #define OSPFv3RESTARTAGE 19
56 #define OSPFv3RESTARTEXITREASON 20
57 #define OSPFv3NOTIFICATIONENABLE 21
58 #define OSPFv3STUBROUTERSUPPORT 22
59 #define OSPFv3STUBROUTERADVERTISEMENT 23
60 #define OSPFv3DISCONTINUITYTIME 24
61 #define OSPFv3RESTARTTIME 25
63 /* OSPFv3 MIB Area Table values: ospfv3AreaTable */
64 #define OSPFv3IMPORTASEXTERN 2
65 #define OSPFv3AREASPFRUNS 3
66 #define OSPFv3AREABDRRTRCOUNT 4
67 #define OSPFv3AREAASBDRRTRCOUNT 5
68 #define OSPFv3AREASCOPELSACOUNT 6
69 #define OSPFv3AREASCOPELSACKSUMSUM 7
70 #define OSPFv3AREASUMMARY 8
71 #define OSPFv3AREAROWSTATUS 9
72 #define OSPFv3AREASTUBMETRIC 10
73 #define OSPFv3AREANSSATRANSLATORROLE 11
74 #define OSPFv3AREANSSATRANSLATORSTATE 12
75 #define OSPFv3AREANSSATRANSLATORSTABINTERVAL 13
76 #define OSPFv3AREANSSATRANSLATOREVENTS 14
77 #define OSPFv3AREASTUBMETRICTYPE 15
78 #define OSPFv3AREATEENABLED 16
80 /* OSPFv3 MIB * Lsdb Table values: ospfv3*LsdbTable */
81 #define OSPFv3WWLSDBSEQUENCE 1
82 #define OSPFv3WWLSDBAGE 2
83 #define OSPFv3WWLSDBCHECKSUM 3
84 #define OSPFv3WWLSDBADVERTISEMENT 4
85 #define OSPFv3WWLSDBTYPEKNOWN 5
87 /* Three first bits are to identify column */
88 #define OSPFv3WWCOLUMN 0x7
89 /* Then we use other bits to identify table */
90 #define OSPFv3WWASTABLE (1 << 3)
91 #define OSPFv3WWAREATABLE (1 << 4)
92 #define OSPFv3WWLINKTABLE (1 << 5)
93 #define OSPFv3WWVIRTLINKTABLE (1 << 6)
95 /* OSPFv3 MIB Host Table values: ospfv3HostTable */
96 #define OSPFv3HOSTMETRIC 3
97 #define OSPFv3HOSTROWSTATUS 4
98 #define OSPFv3HOSTAREAID 5
100 /* OSPFv3 MIB Interface Table values: ospfv3IfTable */
101 #define OSPFv3IFAREAID 3
102 #define OSPFv3IFTYPE 4
103 #define OSPFv3IFADMINSTATUS 5
104 #define OSPFv3IFRTRPRIORITY 6
105 #define OSPFv3IFTRANSITDELAY 7
106 #define OSPFv3IFRETRANSINTERVAL 8
107 #define OSPFv3IFHELLOINTERVAL 9
108 #define OSPFv3IFRTRDEADINTERVAL 10
109 #define OSPFv3IFPOLLINTERVAL 11
110 #define OSPFv3IFSTATE 12
111 #define OSPFv3IFDESIGNATEDROUTER 13
112 #define OSPFv3IFBACKUPDESIGNATEDROUTER 14
113 #define OSPFv3IFEVENTS 15
114 #define OSPFv3IFROWSTATUS 16
115 #define OSPFv3IFDEMAND 17
116 #define OSPFv3IFMETRICVALUE 18
117 #define OSPFv3IFLINKSCOPELSACOUNT 19
118 #define OSPFv3IFLINKLSACKSUMSUM 20
119 #define OSPFv3IFDEMANDNBRPROBE 21
120 #define OSPFv3IFDEMANDNBRPROBERETRANSLIMIT 22
121 #define OSPFv3IFDEMANDNBRPROBEINTERVAL 23
122 #define OSPFv3IFTEDISABLED 24
123 #define OSPFv3IFLINKLSASUPPRESSION 25
125 /* OSPFv3 MIB Virtual Interface Table values: ospfv3VirtIfTable */
126 #define OSPFv3VIRTIFINDEX 3
127 #define OSPFv3VIRTIFINSTID 4
128 #define OSPFv3VIRTIFTRANSITDELAY 5
129 #define OSPFv3VIRTIFRETRANSINTERVAL 6
130 #define OSPFv3VIRTIFHELLOINTERVAL 7
131 #define OSPFv3VIRTIFRTRDEADINTERVAL 8
132 #define OSPFv3VIRTIFSTATE 9
133 #define OSPFv3VIRTIFEVENTS 10
134 #define OSPFv3VIRTIFROWSTATUS 11
135 #define OSPFv3VIRTIFLINKSCOPELSACOUNT 12
136 #define OSPFv3VIRTIFLINKLSACKSUMSUM 13
138 /* OSPFv3 MIB Neighbors Table values: ospfv3NbrTable */
139 #define OSPFv3NBRADDRESSTYPE 4
140 #define OSPFv3NBRADDRESS 5
141 #define OSPFv3NBROPTIONS 6
142 #define OSPFv3NBRPRIORITY 7
143 #define OSPFv3NBRSTATE 8
144 #define OSPFv3NBREVENTS 9
145 #define OSPFv3NBRLSRETRANSQLEN 10
146 #define OSPFv3NBRHELLOSUPPRESSED 11
147 #define OSPFv3NBRIFID 12
148 #define OSPFv3NBRRESTARTHELPERSTATUS 13
149 #define OSPFv3NBRRESTARTHELPERAGE 14
150 #define OSPFv3NBRRESTARTHELPEREXITREASON 15
152 /* OSPFv3 MIB Configured Neighbors Table values: ospfv3CfgNbrTable */
153 #define OSPFv3CFGNBRPRIORITY 5
154 #define OSPFv3CFGNBRROWSTATUS 6
156 /* OSPFv3 MIB Virtual Neighbors Table values: ospfv3VirtNbrTable */
157 #define OSPFv3VIRTNBRIFINDEX 3
158 #define OSPFv3VIRTNBRIFINSTID 4
159 #define OSPFv3VIRTNBRADDRESSTYPE 5
160 #define OSPFv3VIRTNBRADDRESS 6
161 #define OSPFv3VIRTNBROPTIONS 7
162 #define OSPFv3VIRTNBRSTATE 8
163 #define OSPFv3VIRTNBREVENTS 9
164 #define OSPFv3VIRTNBRLSRETRANSQLEN 10
165 #define OSPFv3VIRTNBRHELLOSUPPRESSED 11
166 #define OSPFv3VIRTNBRIFID 12
167 #define OSPFv3VIRTNBRRESTARTHELPERSTATUS 13
168 #define OSPFv3VIRTNBRRESTARTHELPERAGE 14
169 #define OSPFv3VIRTNBRRESTARTHELPEREXITREASON 15
171 /* OSPFv3 MIB Area Aggregate Table values: ospfv3AreaAggregateTable */
172 #define OSPFv3AREAAGGREGATEROWSTATUS 6
173 #define OSPFv3AREAAGGREGATEEFFECT 7
174 #define OSPFv3AREAAGGREGATEROUTETAG 8
176 /* SYNTAX Status from OSPF-MIB. */
177 #define OSPF_STATUS_ENABLED 1
178 #define OSPF_STATUS_DISABLED 2
180 /* SNMP value hack. */
181 #define COUNTER ASN_COUNTER
182 #define INTEGER ASN_INTEGER
183 #define GAUGE ASN_GAUGE
184 #define UNSIGNED ASN_UNSIGNED
185 #define TIMETICKS ASN_TIMETICKS
186 #define IPADDRESS ASN_IPADDRESS
187 #define STRING ASN_OCTET_STR
189 /* For return values e.g. SNMP_INTEGER macro */
192 /* OSPFv3-MIB instances. */
193 static oid ospfv3_oid
[] = {OSPFv3MIB
};
194 static oid ospfv3_trap_oid
[] = {OSPFv3MIB
, 0};
196 /* Hook functions. */
197 static uint8_t *ospfv3GeneralGroup(struct variable
*, oid
*, size_t *, int,
198 size_t *, WriteMethod
**);
199 static uint8_t *ospfv3AreaEntry(struct variable
*, oid
*, size_t *, int,
200 size_t *, WriteMethod
**);
201 static uint8_t *ospfv3WwLsdbEntry(struct variable
*, oid
*, size_t *, int,
202 size_t *, WriteMethod
**);
203 static uint8_t *ospfv3NbrEntry(struct variable
*, oid
*, size_t *, int,
204 size_t *, WriteMethod
**);
205 static uint8_t *ospfv3IfEntry(struct variable
*, oid
*, size_t *, int, size_t *,
208 static struct variable ospfv3_variables
[] = {
209 /* OSPF general variables */
210 {OSPFv3ROUTERID
, UNSIGNED
, RWRITE
, ospfv3GeneralGroup
, 3, {1, 1, 1}},
211 {OSPFv3ADMINSTAT
, INTEGER
, RWRITE
, ospfv3GeneralGroup
, 3, {1, 1, 2}},
212 {OSPFv3VERSIONNUMBER
, INTEGER
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 3}},
213 {OSPFv3AREABDRRTRSTATUS
,
219 {OSPFv3ASBDRRTRSTATUS
,
225 {OSPFv3ASSCOPELSACOUNT
, GAUGE
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 6}},
226 {OSPFv3ASSCOPELSACHECKSUMSUM
,
232 {OSPFv3ORIGINATENEWLSAS
,
238 {OSPFv3RXNEWLSAS
, COUNTER
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 9}},
239 {OSPFv3EXTLSACOUNT
, GAUGE
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 10}},
240 {OSPFv3EXTAREALSDBLIMIT
,
246 {OSPFv3EXITOVERFLOWINTERVAL
,
252 {OSPFv3DEMANDEXTENSIONS
,
258 {OSPFv3REFERENCEBANDWIDTH
,
264 {OSPFv3RESTARTSUPPORT
,
270 {OSPFv3RESTARTINTERVAL
,
276 {OSPFv3RESTARTSTRICTLSACHECKING
,
282 {OSPFv3RESTARTSTATUS
,
288 {OSPFv3RESTARTAGE
, UNSIGNED
, RONLY
, ospfv3GeneralGroup
, 3, {1, 1, 19}},
289 {OSPFv3RESTARTEXITREASON
,
295 {OSPFv3NOTIFICATIONENABLE
,
301 {OSPFv3STUBROUTERSUPPORT
,
307 {OSPFv3STUBROUTERADVERTISEMENT
,
313 {OSPFv3DISCONTINUITYTIME
,
326 /* OSPFv3 Area Data Structure */
327 {OSPFv3IMPORTASEXTERN
,
333 {OSPFv3AREASPFRUNS
, COUNTER
, RONLY
, ospfv3AreaEntry
, 4, {1, 2, 1, 3}},
334 {OSPFv3AREABDRRTRCOUNT
, GAUGE
, RONLY
, ospfv3AreaEntry
, 4, {1, 2, 1, 4}},
335 {OSPFv3AREAASBDRRTRCOUNT
,
341 {OSPFv3AREASCOPELSACOUNT
,
347 {OSPFv3AREASCOPELSACKSUMSUM
,
353 {OSPFv3AREASUMMARY
, INTEGER
, RWRITE
, ospfv3AreaEntry
, 4, {1, 2, 1, 8}},
354 {OSPFv3AREAROWSTATUS
,
360 {OSPFv3AREASTUBMETRIC
,
366 {OSPFv3AREANSSATRANSLATORROLE
,
372 {OSPFv3AREANSSATRANSLATORSTATE
,
378 {OSPFv3AREANSSATRANSLATORSTABINTERVAL
,
384 {OSPFv3AREANSSATRANSLATOREVENTS
,
390 {OSPFv3AREASTUBMETRICTYPE
,
396 {OSPFv3AREATEENABLED
,
404 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWASTABLE
,
410 {OSPFv3WWLSDBAGE
| OSPFv3WWASTABLE
,
416 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWASTABLE
,
422 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWASTABLE
,
428 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWASTABLE
,
435 /* OSPFv3 Area LSDB */
436 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWAREATABLE
,
442 {OSPFv3WWLSDBAGE
| OSPFv3WWAREATABLE
,
448 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWAREATABLE
,
454 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWAREATABLE
,
460 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWAREATABLE
,
467 /* OSPFv3 Link LSDB */
468 {OSPFv3WWLSDBSEQUENCE
| OSPFv3WWLINKTABLE
,
474 {OSPFv3WWLSDBAGE
| OSPFv3WWLINKTABLE
,
480 {OSPFv3WWLSDBCHECKSUM
| OSPFv3WWLINKTABLE
,
486 {OSPFv3WWLSDBADVERTISEMENT
| OSPFv3WWLINKTABLE
,
492 {OSPFv3WWLSDBTYPEKNOWN
| OSPFv3WWLINKTABLE
,
499 /* OSPFv3 interfaces */
500 {OSPFv3IFAREAID
, UNSIGNED
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 3}},
501 {OSPFv3IFTYPE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 4}},
502 {OSPFv3IFADMINSTATUS
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 5}},
503 {OSPFv3IFRTRPRIORITY
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 6}},
504 {OSPFv3IFTRANSITDELAY
, UNSIGNED
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 7}},
505 {OSPFv3IFRETRANSINTERVAL
,
511 {OSPFv3IFHELLOINTERVAL
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 9}},
512 {OSPFv3IFRTRDEADINTERVAL
,
518 {OSPFv3IFPOLLINTERVAL
,
524 {OSPFv3IFSTATE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 12}},
525 {OSPFv3IFDESIGNATEDROUTER
,
531 {OSPFv3IFBACKUPDESIGNATEDROUTER
,
537 {OSPFv3IFEVENTS
, COUNTER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 15}},
538 {OSPFv3IFROWSTATUS
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 16}},
539 {OSPFv3IFDEMAND
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 17}},
540 {OSPFv3IFMETRICVALUE
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 18}},
541 {OSPFv3IFLINKSCOPELSACOUNT
,
547 {OSPFv3IFLINKLSACKSUMSUM
,
553 {OSPFv3IFDEMANDNBRPROBE
,
559 {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT
,
565 {OSPFv3IFDEMANDNBRPROBEINTERVAL
,
571 {OSPFv3IFTEDISABLED
, INTEGER
, RONLY
, ospfv3IfEntry
, 4, {1, 7, 1, 24}},
572 {OSPFv3IFLINKLSASUPPRESSION
,
579 /* OSPFv3 neighbors */
580 {OSPFv3NBRADDRESSTYPE
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 4}},
581 {OSPFv3NBRADDRESS
, STRING
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 5}},
582 {OSPFv3NBROPTIONS
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 6}},
583 {OSPFv3NBRPRIORITY
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 7}},
584 {OSPFv3NBRSTATE
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 8}},
585 {OSPFv3NBREVENTS
, COUNTER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 9}},
586 {OSPFv3NBRLSRETRANSQLEN
,
592 {OSPFv3NBRHELLOSUPPRESSED
,
598 {OSPFv3NBRIFID
, INTEGER
, RONLY
, ospfv3NbrEntry
, 4, {1, 9, 1, 12}},
599 {OSPFv3NBRRESTARTHELPERSTATUS
,
605 {OSPFv3NBRRESTARTHELPERAGE
,
611 {OSPFv3NBRRESTARTHELPEREXITREASON
,
619 static uint8_t *ospfv3GeneralGroup(struct variable
*v
, oid
*name
,
620 size_t *length
, int exact
, size_t *var_len
,
621 WriteMethod
**write_method
)
625 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
628 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
629 /* Check whether the instance identifier is valid */
630 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
634 /* Return the current value of the variable */
637 /* Router-ID of this OSPF instance. */
639 return SNMP_INTEGER(ntohl(ospf6
->router_id
));
640 return SNMP_INTEGER(0);
641 case OSPFv3ADMINSTAT
:
644 CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
)
645 ? OSPF_STATUS_DISABLED
646 : OSPF_STATUS_ENABLED
);
647 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
648 case OSPFv3VERSIONNUMBER
:
649 return SNMP_INTEGER(3);
650 case OSPFv3AREABDRRTRSTATUS
:
653 ospf6_check_and_set_router_abr(ospf6
)
656 return SNMP_INTEGER(SNMP_FALSE
);
657 case OSPFv3ASBDRRTRSTATUS
:
659 return SNMP_INTEGER(ospf6_asbr_is_asbr(ospf6
)
662 return SNMP_INTEGER(SNMP_FALSE
);
663 case OSPFv3ASSCOPELSACOUNT
:
665 return SNMP_INTEGER(ospf6
->lsdb
->count
);
666 return SNMP_INTEGER(0);
667 case OSPFv3ASSCOPELSACHECKSUMSUM
:
670 for (ALL_LSDB(ospf6
->lsdb
, lsa
, lsanext
))
671 sum
+= ntohs(lsa
->header
->checksum
);
672 return SNMP_INTEGER(sum
);
674 return SNMP_INTEGER(0);
675 case OSPFv3ORIGINATENEWLSAS
:
677 0); /* Don't know where to get this value... */
678 case OSPFv3RXNEWLSAS
:
680 0); /* Don't know where to get this value... */
681 case OSPFv3EXTLSACOUNT
:
684 for (ALL_LSDB_TYPED(ospf6
->lsdb
,
685 htons(OSPF6_LSTYPE_AS_EXTERNAL
),
688 return SNMP_INTEGER(count
);
690 return SNMP_INTEGER(0);
691 case OSPFv3EXTAREALSDBLIMIT
:
692 return SNMP_INTEGER(-1);
693 case OSPFv3EXITOVERFLOWINTERVAL
:
694 return SNMP_INTEGER(0); /* Not supported */
695 case OSPFv3DEMANDEXTENSIONS
:
696 return SNMP_INTEGER(0); /* Not supported */
697 case OSPFv3REFERENCEBANDWIDTH
:
699 return SNMP_INTEGER(ospf6
->ref_bandwidth
);
700 /* Otherwise, like for "not implemented". */
702 case OSPFv3RESTARTSUPPORT
:
703 case OSPFv3RESTARTINTERVAL
:
704 case OSPFv3RESTARTSTRICTLSACHECKING
:
705 case OSPFv3RESTARTSTATUS
:
706 case OSPFv3RESTARTAGE
:
707 case OSPFv3RESTARTEXITREASON
:
708 case OSPFv3NOTIFICATIONENABLE
:
709 case OSPFv3STUBROUTERSUPPORT
:
710 case OSPFv3STUBROUTERADVERTISEMENT
:
711 case OSPFv3DISCONTINUITYTIME
:
712 case OSPFv3RESTARTTIME
:
713 /* TODO: Not implemented */
719 static uint8_t *ospfv3AreaEntry(struct variable
*v
, oid
*name
, size_t *length
,
720 int exact
, size_t *var_len
,
721 WriteMethod
**write_method
)
723 struct ospf6_area
*oa
, *area
= NULL
;
724 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
725 uint32_t area_id
= 0;
728 struct listnode
*node
;
731 struct ospf6_route
*ro
;
734 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
739 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
743 len
= *length
- v
->namelen
;
744 len
= (len
>= 1 ? 1 : 0);
745 if (exact
&& len
!= 1)
748 area_id
= htonl(name
[v
->namelen
]);
750 inet_ntop(AF_INET
, &area_id
, a
, sizeof(a
));
751 zlog_debug("SNMP access by area: %s, exact=%d len=%d length=%lu", a
,
752 exact
, len
, (unsigned long)*length
);
754 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
756 if (len
== 0) /* return first area entry */
758 else if (exact
&& ntohl(oa
->area_id
) == ntohl(area_id
))
760 else if (ntohl(oa
->area_id
) > ntohl(area_id
))
768 *length
= v
->namelen
+ 1;
769 name
[v
->namelen
] = ntohl(area
->area_id
);
771 inet_ntop(AF_INET
, &area
->area_id
, a
, sizeof(a
));
772 zlog_debug("SNMP found area: %s, exact=%d len=%d length=%lu", a
, exact
,
773 len
, (unsigned long)*length
);
776 case OSPFv3IMPORTASEXTERN
:
777 /* No NSSA support */
778 return SNMP_INTEGER(IS_AREA_STUB(area
) ? 2 : 1);
779 case OSPFv3AREASPFRUNS
:
780 return SNMP_INTEGER(area
->spf_calculation
);
781 case OSPFv3AREABDRRTRCOUNT
:
782 case OSPFv3AREAASBDRRTRCOUNT
:
784 for (ro
= ospf6_route_head(ospf6
->brouter_table
); ro
;
785 ro
= ospf6_route_next(ro
)) {
786 if (ntohl(ro
->path
.area_id
) != ntohl(area
->area_id
))
788 if (v
->magic
== OSPFv3AREABDRRTRCOUNT
789 && CHECK_FLAG(ro
->path
.router_bits
,
792 if (v
->magic
== OSPFv3AREAASBDRRTRCOUNT
793 && CHECK_FLAG(ro
->path
.router_bits
,
797 return SNMP_INTEGER(count
);
798 case OSPFv3AREASCOPELSACOUNT
:
799 return SNMP_INTEGER(area
->lsdb
->count
);
800 case OSPFv3AREASCOPELSACKSUMSUM
:
802 for (ALL_LSDB(area
->lsdb
, lsa
, lsanext
))
803 sum
+= ntohs(lsa
->header
->checksum
);
804 return SNMP_INTEGER(sum
);
805 case OSPFv3AREASUMMARY
:
806 return SNMP_INTEGER(2); /* sendAreaSummary */
807 case OSPFv3AREAROWSTATUS
:
808 return SNMP_INTEGER(1); /* Active */
809 case OSPFv3AREASTUBMETRIC
:
810 case OSPFv3AREANSSATRANSLATORROLE
:
811 case OSPFv3AREANSSATRANSLATORSTATE
:
812 case OSPFv3AREANSSATRANSLATORSTABINTERVAL
:
813 case OSPFv3AREANSSATRANSLATOREVENTS
:
814 case OSPFv3AREASTUBMETRICTYPE
:
815 case OSPFv3AREATEENABLED
:
816 /* Not implemented. */
822 static int if_icmp_func(struct interface
*ifp1
, struct interface
*ifp2
)
824 return (ifp1
->ifindex
- ifp2
->ifindex
);
827 static uint8_t *ospfv3WwLsdbEntry(struct variable
*v
, oid
*name
, size_t *length
,
828 int exact
, size_t *var_len
,
829 WriteMethod
**write_method
)
832 struct ospf6_lsa
*lsa
= NULL
;
834 uint32_t area_id
, id
, instid
, adv_router
;
839 struct ospf6_area
*oa
= NULL
;
840 struct listnode
*node
;
841 struct interface
*iif
;
842 struct ospf6_interface
*oi
= NULL
;
843 struct list
*ifslist
;
846 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
848 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
852 instid
= ifindex
= area_id
= type
= id
= adv_router
= 0;
854 /* Check OSPFv3 instance. */
858 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
859 /* Get variable length. */
860 offset
= name
+ v
->namelen
;
861 offsetlen
= *length
- v
->namelen
;
863 if (exact
&& (v
->magic
& OSPFv3WWASTABLE
) && offsetlen
!= 3)
865 if (exact
&& (v
->magic
& OSPFv3WWAREATABLE
) && offsetlen
!= 4)
867 if (exact
&& (v
->magic
& OSPFv3WWLINKTABLE
) && offsetlen
!= 5)
870 if (v
->magic
& OSPFv3WWLINKTABLE
) {
872 len
= (offsetlen
< 1 ? 0 : 1);
878 /* Parse instance ID */
879 len
= (offsetlen
< 1 ? 0 : 1);
884 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
886 len
= (offsetlen
< 1 ? 0 : 1);
888 area_id
= htonl(*offset
);
894 len
= (offsetlen
< 1 ? 0 : 1);
896 type
= htons(*offset
);
900 /* Parse Router-ID */
901 len
= (offsetlen
< 1 ? 0 : 1);
903 adv_router
= htonl(*offset
);
908 len
= (offsetlen
< 1 ? 0 : 1);
912 // offsetlen -= len; // Add back in if we need it again
915 if (v
->magic
& OSPFv3WWASTABLE
) {
916 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
,
918 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
919 oa
= ospf6_area_lookup(area_id
, ospf6
);
922 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, oa
->lsdb
);
923 } else if (v
->magic
& OSPFv3WWLINKTABLE
) {
924 oi
= ospf6_interface_lookup_by_ifindex(ifindex
,
926 if (!oi
|| oi
->instance_id
!= instid
)
928 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, oi
->lsdb
);
931 if (v
->magic
& OSPFv3WWASTABLE
) {
932 if (ospf6
->lsdb
->count
)
933 lsa
= ospf6_lsdb_lookup_next(
934 type
, id
, adv_router
, ospf6
->lsdb
);
935 } else if (v
->magic
& OSPFv3WWAREATABLE
)
936 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
937 if (oa
->area_id
< area_id
)
941 lsa
= ospf6_lsdb_lookup_next(
942 type
, id
, adv_router
, oa
->lsdb
);
949 else if (v
->magic
& OSPFv3WWLINKTABLE
) {
950 /* We build a sorted list of interfaces */
951 ifslist
= list_new();
952 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
953 FOR_ALL_INTERFACES (vrf
, iif
)
954 listnode_add_sort(ifslist
, iif
);
956 for (ALL_LIST_ELEMENTS_RO(ifslist
, node
, iif
)) {
962 if (iif
->ifindex
< ifindex
)
964 if (oi
->instance_id
< instid
)
968 lsa
= ospf6_lsdb_lookup_next(
969 type
, id
, adv_router
, oi
->lsdb
);
978 list_delete_all_node(ifslist
);
979 list_delete(&ifslist
);
987 if (v
->magic
& OSPFv3WWASTABLE
) {
988 *length
= v
->namelen
+ 3;
989 offset
= name
+ v
->namelen
;
990 } else if (v
->magic
& OSPFv3WWAREATABLE
) {
991 *length
= v
->namelen
+ 4;
992 offset
= name
+ v
->namelen
;
993 *offset
= ntohl(oa
->area_id
);
995 } else if (v
->magic
& OSPFv3WWLINKTABLE
) {
996 *length
= v
->namelen
+ 5;
997 offset
= name
+ v
->namelen
;
998 *offset
= oi
->interface
->ifindex
;
1000 *offset
= oi
->instance_id
;
1003 *offset
= ntohs(lsa
->header
->type
);
1005 *offset
= ntohl(lsa
->header
->adv_router
);
1007 *offset
= ntohl(lsa
->header
->id
);
1010 /* Return the current value of the variable */
1011 switch (v
->magic
& OSPFv3WWCOLUMN
) {
1012 case OSPFv3WWLSDBSEQUENCE
:
1013 return SNMP_INTEGER(ntohl(lsa
->header
->seqnum
));
1014 case OSPFv3WWLSDBAGE
:
1015 ospf6_lsa_age_current(lsa
);
1016 return SNMP_INTEGER(ntohs(lsa
->header
->age
));
1017 case OSPFv3WWLSDBCHECKSUM
:
1018 return SNMP_INTEGER(ntohs(lsa
->header
->checksum
));
1019 case OSPFv3WWLSDBADVERTISEMENT
:
1020 *var_len
= ntohs(lsa
->header
->length
);
1021 return (uint8_t *)lsa
->header
;
1022 case OSPFv3WWLSDBTYPEKNOWN
:
1023 return SNMP_INTEGER(OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
1030 static uint8_t *ospfv3IfEntry(struct variable
*v
, oid
*name
, size_t *length
,
1031 int exact
, size_t *var_len
,
1032 WriteMethod
**write_method
)
1035 ifindex_t ifindex
= 0;
1036 unsigned int instid
= 0;
1037 struct ospf6_interface
*oi
= NULL
;
1038 struct ospf6_lsa
*lsa
= NULL
, *lsanext
;
1039 struct interface
*iif
;
1041 struct list
*ifslist
;
1045 struct ospf6
*ospf6
;
1047 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
1049 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1053 /* Check OSPFv3 instance. */
1057 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1058 /* Get variable length. */
1059 offset
= name
+ v
->namelen
;
1060 offsetlen
= *length
- v
->namelen
;
1062 if (exact
&& offsetlen
!= 2)
1065 /* Parse if index */
1066 len
= (offsetlen
< 1 ? 0 : 1);
1072 /* Parse instance ID */
1073 len
= (offsetlen
< 1 ? 0 : 1);
1076 // offset += len; // Add back in if we ever start using again
1077 // offsetlen -= len;
1080 oi
= ospf6_interface_lookup_by_ifindex(ifindex
, ospf6
->vrf_id
);
1081 if (!oi
|| oi
->instance_id
!= instid
)
1084 /* We build a sorted list of interfaces */
1085 ifslist
= list_new();
1086 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
1087 FOR_ALL_INTERFACES (vrf
, iif
)
1088 listnode_add_sort(ifslist
, iif
);
1090 for (ALL_LIST_ELEMENTS_RO(ifslist
, i
, iif
)) {
1096 if (iif
->ifindex
> ifindex
1097 || (iif
->ifindex
== ifindex
1098 && (oi
->instance_id
> instid
)))
1103 list_delete_all_node(ifslist
);
1104 list_delete(&ifslist
);
1110 /* Add Index (IfIndex, IfInstId) */
1111 *length
= v
->namelen
+ 2;
1112 offset
= name
+ v
->namelen
;
1113 *offset
= oi
->interface
->ifindex
;
1115 *offset
= oi
->instance_id
;
1118 /* Return the current value of the variable */
1120 case OSPFv3IFAREAID
:
1122 return SNMP_INTEGER(ntohl(oi
->area
->area_id
));
1125 if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
1126 return SNMP_INTEGER(1);
1127 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
1128 return SNMP_INTEGER(3);
1130 break; /* Unknown, don't put anything */
1131 case OSPFv3IFADMINSTATUS
:
1133 return SNMP_INTEGER(OSPF_STATUS_ENABLED
);
1134 return SNMP_INTEGER(OSPF_STATUS_DISABLED
);
1135 case OSPFv3IFRTRPRIORITY
:
1136 return SNMP_INTEGER(oi
->priority
);
1137 case OSPFv3IFTRANSITDELAY
:
1138 return SNMP_INTEGER(oi
->transdelay
);
1139 case OSPFv3IFRETRANSINTERVAL
:
1140 return SNMP_INTEGER(oi
->rxmt_interval
);
1141 case OSPFv3IFHELLOINTERVAL
:
1142 return SNMP_INTEGER(oi
->hello_interval
);
1143 case OSPFv3IFRTRDEADINTERVAL
:
1144 return SNMP_INTEGER(oi
->dead_interval
);
1145 case OSPFv3IFPOLLINTERVAL
:
1146 /* No support for NBMA */
1149 return SNMP_INTEGER(oi
->state
);
1150 case OSPFv3IFDESIGNATEDROUTER
:
1151 return SNMP_INTEGER(ntohl(oi
->drouter
));
1152 case OSPFv3IFBACKUPDESIGNATEDROUTER
:
1153 return SNMP_INTEGER(ntohl(oi
->bdrouter
));
1154 case OSPFv3IFEVENTS
:
1155 return SNMP_INTEGER(oi
->state_change
);
1156 case OSPFv3IFROWSTATUS
:
1157 return SNMP_INTEGER(1);
1158 case OSPFv3IFDEMAND
:
1159 return SNMP_INTEGER(SNMP_FALSE
);
1160 case OSPFv3IFMETRICVALUE
:
1161 return SNMP_INTEGER(oi
->cost
);
1162 case OSPFv3IFLINKSCOPELSACOUNT
:
1163 return SNMP_INTEGER(oi
->lsdb
->count
);
1164 case OSPFv3IFLINKLSACKSUMSUM
:
1166 for (ALL_LSDB(oi
->lsdb
, lsa
, lsanext
))
1167 sum
+= ntohs(lsa
->header
->checksum
);
1168 return SNMP_INTEGER(sum
);
1169 case OSPFv3IFDEMANDNBRPROBE
:
1170 case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT
:
1171 case OSPFv3IFDEMANDNBRPROBEINTERVAL
:
1172 case OSPFv3IFTEDISABLED
:
1173 case OSPFv3IFLINKLSASUPPRESSION
:
1174 /* Not implemented. Only works if all the last ones are not
1179 /* Try an internal getnext. Some columns are missing in this table. */
1180 if (!exact
&& (name
[*length
- 1] < MAX_SUBID
))
1181 return ospfv3IfEntry(v
, name
, length
, exact
, var_len
,
1186 static uint8_t *ospfv3NbrEntry(struct variable
*v
, oid
*name
, size_t *length
,
1187 int exact
, size_t *var_len
,
1188 WriteMethod
**write_method
)
1191 ifindex_t ifindex
= 0;
1192 unsigned int instid
, rtrid
;
1193 struct ospf6_interface
*oi
= NULL
;
1194 struct ospf6_neighbor
*on
= NULL
;
1195 struct interface
*iif
;
1196 struct listnode
*i
, *j
;
1197 struct list
*ifslist
;
1200 struct ospf6
*ospf6
;
1202 ospf6
= ospf6_lookup_by_vrf_id(VRF_DEFAULT
);
1204 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
1210 /* Check OSPFv3 instance. */
1214 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
1215 /* Get variable length. */
1216 offset
= name
+ v
->namelen
;
1217 offsetlen
= *length
- v
->namelen
;
1219 if (exact
&& offsetlen
!= 3)
1222 /* Parse if index */
1223 len
= (offsetlen
< 1 ? 0 : 1);
1229 /* Parse instance ID */
1230 len
= (offsetlen
< 1 ? 0 : 1);
1236 /* Parse router ID */
1237 len
= (offsetlen
< 1 ? 0 : 1);
1239 rtrid
= htonl(*offset
);
1240 // offset += len; // Add back in if we ever start looking at data
1241 // offsetlen -= len;
1244 oi
= ospf6_interface_lookup_by_ifindex(ifindex
, ospf6
->vrf_id
);
1245 if (!oi
|| oi
->instance_id
!= instid
)
1247 on
= ospf6_neighbor_lookup(rtrid
, oi
);
1249 /* We build a sorted list of interfaces */
1250 ifslist
= list_new();
1251 ifslist
->cmp
= (int (*)(void *, void *))if_icmp_func
;
1252 FOR_ALL_INTERFACES (vrf
, iif
)
1253 listnode_add_sort(ifslist
, iif
);
1255 for (ALL_LIST_ELEMENTS_RO(ifslist
, i
, iif
)) {
1261 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, j
, on
)) {
1262 if (iif
->ifindex
> ifindex
1263 || (iif
->ifindex
== ifindex
1264 && (oi
->instance_id
> instid
1265 || (oi
->instance_id
== instid
1266 && ntohl(on
->router_id
)
1276 list_delete_all_node(ifslist
);
1277 list_delete(&ifslist
);
1283 /* Add Index (IfIndex, IfInstId, RtrId) */
1284 *length
= v
->namelen
+ 3;
1285 offset
= name
+ v
->namelen
;
1286 *offset
= oi
->interface
->ifindex
;
1288 *offset
= oi
->instance_id
;
1290 *offset
= ntohl(on
->router_id
);
1293 /* Return the current value of the variable */
1295 case OSPFv3NBRADDRESSTYPE
:
1296 return SNMP_INTEGER(2); /* IPv6 only */
1297 case OSPFv3NBRADDRESS
:
1298 *var_len
= sizeof(struct in6_addr
);
1299 return (uint8_t *)&on
->linklocal_addr
;
1300 case OSPFv3NBROPTIONS
:
1301 return SNMP_INTEGER(on
->options
[2]);
1302 case OSPFv3NBRPRIORITY
:
1303 return SNMP_INTEGER(on
->priority
);
1304 case OSPFv3NBRSTATE
:
1305 return SNMP_INTEGER(on
->state
);
1306 case OSPFv3NBREVENTS
:
1307 return SNMP_INTEGER(on
->state_change
);
1308 case OSPFv3NBRLSRETRANSQLEN
:
1309 return SNMP_INTEGER(on
->retrans_list
->count
);
1310 case OSPFv3NBRHELLOSUPPRESSED
:
1311 return SNMP_INTEGER(SNMP_FALSE
);
1313 return SNMP_INTEGER(on
->ifindex
);
1314 case OSPFv3NBRRESTARTHELPERSTATUS
:
1315 case OSPFv3NBRRESTARTHELPERAGE
:
1316 case OSPFv3NBRRESTARTHELPEREXITREASON
:
1317 /* Not implemented. Only works if all the last ones are not
1326 #define NBRSTATECHANGE 2
1327 #define IFSTATECHANGE 10
1329 static struct trap_object ospf6NbrTrapList
[] = {
1330 {-3, {1, 1, OSPFv3ROUTERID
}},
1331 {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE
}},
1332 {4, {1, 9, 1, OSPFv3NBRADDRESS
}},
1333 {4, {1, 9, 1, OSPFv3NBRSTATE
}}};
1335 static struct trap_object ospf6IfTrapList
[] = {
1336 {-3, {1, 1, OSPFv3ROUTERID
}},
1337 {4, {1, 7, 1, OSPFv3IFSTATE
}},
1338 {4, {1, 7, 1, OSPFv3IFADMINSTATUS
}},
1339 {4, {1, 7, 1, OSPFv3IFAREAID
}}};
1341 static int ospf6TrapNbrStateChange(struct ospf6_neighbor
*on
, int next_state
,
1346 /* Terminal state or regression */
1347 if ((next_state
!= OSPF6_NEIGHBOR_FULL
)
1348 && (next_state
!= OSPF6_NEIGHBOR_TWOWAY
)
1349 && (next_state
>= prev_state
))
1352 index
[0] = on
->ospf6_if
->interface
->ifindex
;
1353 index
[1] = on
->ospf6_if
->instance_id
;
1354 index
[2] = ntohl(on
->router_id
);
1356 smux_trap(ospfv3_variables
, array_size(ospfv3_variables
),
1357 ospfv3_trap_oid
, array_size(ospfv3_trap_oid
), ospfv3_oid
,
1358 sizeof(ospfv3_oid
) / sizeof(oid
), index
, 3, ospf6NbrTrapList
,
1359 array_size(ospf6NbrTrapList
), NBRSTATECHANGE
);
1363 static int ospf6TrapIfStateChange(struct ospf6_interface
*oi
, int next_state
,
1368 /* Terminal state or regression */
1369 if ((next_state
!= OSPF6_INTERFACE_POINTTOPOINT
)
1370 && (next_state
!= OSPF6_INTERFACE_DROTHER
)
1371 && (next_state
!= OSPF6_INTERFACE_BDR
)
1372 && (next_state
!= OSPF6_INTERFACE_DR
) && (next_state
>= prev_state
))
1375 index
[0] = oi
->interface
->ifindex
;
1376 index
[1] = oi
->instance_id
;
1378 smux_trap(ospfv3_variables
, array_size(ospfv3_variables
),
1379 ospfv3_trap_oid
, array_size(ospfv3_trap_oid
), ospfv3_oid
,
1380 sizeof(ospfv3_oid
) / sizeof(oid
), index
, 2, ospf6IfTrapList
,
1381 array_size(ospf6IfTrapList
), IFSTATECHANGE
);
1385 /* Register OSPFv3-MIB. */
1386 static int ospf6_snmp_init(struct event_loop
*master
)
1389 REGISTER_MIB("OSPFv3MIB", ospfv3_variables
, variable
, ospfv3_oid
);
1393 static int ospf6_snmp_module_init(void)
1395 hook_register(ospf6_interface_change
, ospf6TrapIfStateChange
);
1396 hook_register(ospf6_neighbor_change
, ospf6TrapNbrStateChange
);
1397 hook_register(frr_late_init
, ospf6_snmp_init
);
1401 FRR_MODULE_SETUP(.name
= "ospf6d_snmp", .version
= FRR_VERSION
,
1402 .description
= "ospf6d AgentX SNMP module",
1403 .init
= ospf6_snmp_module_init
,