summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_snmp.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
commite2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch)
treef0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /ospf6d/ospf6_snmp.c
parentInitial commit. (diff)
downloadfrr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz
frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ospf6d/ospf6_snmp.c')
-rw-r--r--ospf6d/ospf6_snmp.c1404
1 files changed, 1404 insertions, 0 deletions
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
new file mode 100644
index 0000000..f88667b
--- /dev/null
+++ b/ospf6d/ospf6_snmp.c
@@ -0,0 +1,1404 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* OSPFv3 SNMP support
+ * Copyright (C) 2004 Yasuhiro Ohara
+ */
+
+#include <zebra.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#include "log.h"
+#include "vty.h"
+#include "linklist.h"
+#include "vector.h"
+#include "vrf.h"
+#include "smux.h"
+#include "libfrr.h"
+#include "lib/version.h"
+
+#include "ospf6_proto.h"
+#include "ospf6_lsa.h"
+#include "ospf6_lsdb.h"
+#include "ospf6_route.h"
+#include "ospf6_top.h"
+#include "ospf6_area.h"
+#include "ospf6_interface.h"
+#include "ospf6_message.h"
+#include "ospf6_neighbor.h"
+#include "ospf6_abr.h"
+#include "ospf6_asbr.h"
+#include "ospf6d.h"
+
+/* OSPFv3-MIB */
+#define OSPFv3MIB 1,3,6,1,2,1,191
+
+/* OSPFv3 MIB General Group values. */
+#define OSPFv3ROUTERID 1
+#define OSPFv3ADMINSTAT 2
+#define OSPFv3VERSIONNUMBER 3
+#define OSPFv3AREABDRRTRSTATUS 4
+#define OSPFv3ASBDRRTRSTATUS 5
+#define OSPFv3ASSCOPELSACOUNT 6
+#define OSPFv3ASSCOPELSACHECKSUMSUM 7
+#define OSPFv3ORIGINATENEWLSAS 8
+#define OSPFv3RXNEWLSAS 9
+#define OSPFv3EXTLSACOUNT 10
+#define OSPFv3EXTAREALSDBLIMIT 11
+#define OSPFv3EXITOVERFLOWINTERVAL 12
+#define OSPFv3DEMANDEXTENSIONS 13
+#define OSPFv3REFERENCEBANDWIDTH 14
+#define OSPFv3RESTARTSUPPORT 15
+#define OSPFv3RESTARTINTERVAL 16
+#define OSPFv3RESTARTSTRICTLSACHECKING 17
+#define OSPFv3RESTARTSTATUS 18
+#define OSPFv3RESTARTAGE 19
+#define OSPFv3RESTARTEXITREASON 20
+#define OSPFv3NOTIFICATIONENABLE 21
+#define OSPFv3STUBROUTERSUPPORT 22
+#define OSPFv3STUBROUTERADVERTISEMENT 23
+#define OSPFv3DISCONTINUITYTIME 24
+#define OSPFv3RESTARTTIME 25
+
+/* OSPFv3 MIB Area Table values: ospfv3AreaTable */
+#define OSPFv3IMPORTASEXTERN 2
+#define OSPFv3AREASPFRUNS 3
+#define OSPFv3AREABDRRTRCOUNT 4
+#define OSPFv3AREAASBDRRTRCOUNT 5
+#define OSPFv3AREASCOPELSACOUNT 6
+#define OSPFv3AREASCOPELSACKSUMSUM 7
+#define OSPFv3AREASUMMARY 8
+#define OSPFv3AREAROWSTATUS 9
+#define OSPFv3AREASTUBMETRIC 10
+#define OSPFv3AREANSSATRANSLATORROLE 11
+#define OSPFv3AREANSSATRANSLATORSTATE 12
+#define OSPFv3AREANSSATRANSLATORSTABINTERVAL 13
+#define OSPFv3AREANSSATRANSLATOREVENTS 14
+#define OSPFv3AREASTUBMETRICTYPE 15
+#define OSPFv3AREATEENABLED 16
+
+/* OSPFv3 MIB * Lsdb Table values: ospfv3*LsdbTable */
+#define OSPFv3WWLSDBSEQUENCE 1
+#define OSPFv3WWLSDBAGE 2
+#define OSPFv3WWLSDBCHECKSUM 3
+#define OSPFv3WWLSDBADVERTISEMENT 4
+#define OSPFv3WWLSDBTYPEKNOWN 5
+
+/* Three first bits are to identify column */
+#define OSPFv3WWCOLUMN 0x7
+/* Then we use other bits to identify table */
+#define OSPFv3WWASTABLE (1 << 3)
+#define OSPFv3WWAREATABLE (1 << 4)
+#define OSPFv3WWLINKTABLE (1 << 5)
+#define OSPFv3WWVIRTLINKTABLE (1 << 6)
+
+/* OSPFv3 MIB Host Table values: ospfv3HostTable */
+#define OSPFv3HOSTMETRIC 3
+#define OSPFv3HOSTROWSTATUS 4
+#define OSPFv3HOSTAREAID 5
+
+/* OSPFv3 MIB Interface Table values: ospfv3IfTable */
+#define OSPFv3IFAREAID 3
+#define OSPFv3IFTYPE 4
+#define OSPFv3IFADMINSTATUS 5
+#define OSPFv3IFRTRPRIORITY 6
+#define OSPFv3IFTRANSITDELAY 7
+#define OSPFv3IFRETRANSINTERVAL 8
+#define OSPFv3IFHELLOINTERVAL 9
+#define OSPFv3IFRTRDEADINTERVAL 10
+#define OSPFv3IFPOLLINTERVAL 11
+#define OSPFv3IFSTATE 12
+#define OSPFv3IFDESIGNATEDROUTER 13
+#define OSPFv3IFBACKUPDESIGNATEDROUTER 14
+#define OSPFv3IFEVENTS 15
+#define OSPFv3IFROWSTATUS 16
+#define OSPFv3IFDEMAND 17
+#define OSPFv3IFMETRICVALUE 18
+#define OSPFv3IFLINKSCOPELSACOUNT 19
+#define OSPFv3IFLINKLSACKSUMSUM 20
+#define OSPFv3IFDEMANDNBRPROBE 21
+#define OSPFv3IFDEMANDNBRPROBERETRANSLIMIT 22
+#define OSPFv3IFDEMANDNBRPROBEINTERVAL 23
+#define OSPFv3IFTEDISABLED 24
+#define OSPFv3IFLINKLSASUPPRESSION 25
+
+/* OSPFv3 MIB Virtual Interface Table values: ospfv3VirtIfTable */
+#define OSPFv3VIRTIFINDEX 3
+#define OSPFv3VIRTIFINSTID 4
+#define OSPFv3VIRTIFTRANSITDELAY 5
+#define OSPFv3VIRTIFRETRANSINTERVAL 6
+#define OSPFv3VIRTIFHELLOINTERVAL 7
+#define OSPFv3VIRTIFRTRDEADINTERVAL 8
+#define OSPFv3VIRTIFSTATE 9
+#define OSPFv3VIRTIFEVENTS 10
+#define OSPFv3VIRTIFROWSTATUS 11
+#define OSPFv3VIRTIFLINKSCOPELSACOUNT 12
+#define OSPFv3VIRTIFLINKLSACKSUMSUM 13
+
+/* OSPFv3 MIB Neighbors Table values: ospfv3NbrTable */
+#define OSPFv3NBRADDRESSTYPE 4
+#define OSPFv3NBRADDRESS 5
+#define OSPFv3NBROPTIONS 6
+#define OSPFv3NBRPRIORITY 7
+#define OSPFv3NBRSTATE 8
+#define OSPFv3NBREVENTS 9
+#define OSPFv3NBRLSRETRANSQLEN 10
+#define OSPFv3NBRHELLOSUPPRESSED 11
+#define OSPFv3NBRIFID 12
+#define OSPFv3NBRRESTARTHELPERSTATUS 13
+#define OSPFv3NBRRESTARTHELPERAGE 14
+#define OSPFv3NBRRESTARTHELPEREXITREASON 15
+
+/* OSPFv3 MIB Configured Neighbors Table values: ospfv3CfgNbrTable */
+#define OSPFv3CFGNBRPRIORITY 5
+#define OSPFv3CFGNBRROWSTATUS 6
+
+/* OSPFv3 MIB Virtual Neighbors Table values: ospfv3VirtNbrTable */
+#define OSPFv3VIRTNBRIFINDEX 3
+#define OSPFv3VIRTNBRIFINSTID 4
+#define OSPFv3VIRTNBRADDRESSTYPE 5
+#define OSPFv3VIRTNBRADDRESS 6
+#define OSPFv3VIRTNBROPTIONS 7
+#define OSPFv3VIRTNBRSTATE 8
+#define OSPFv3VIRTNBREVENTS 9
+#define OSPFv3VIRTNBRLSRETRANSQLEN 10
+#define OSPFv3VIRTNBRHELLOSUPPRESSED 11
+#define OSPFv3VIRTNBRIFID 12
+#define OSPFv3VIRTNBRRESTARTHELPERSTATUS 13
+#define OSPFv3VIRTNBRRESTARTHELPERAGE 14
+#define OSPFv3VIRTNBRRESTARTHELPEREXITREASON 15
+
+/* OSPFv3 MIB Area Aggregate Table values: ospfv3AreaAggregateTable */
+#define OSPFv3AREAAGGREGATEROWSTATUS 6
+#define OSPFv3AREAAGGREGATEEFFECT 7
+#define OSPFv3AREAAGGREGATEROUTETAG 8
+
+/* SYNTAX Status from OSPF-MIB. */
+#define OSPF_STATUS_ENABLED 1
+#define OSPF_STATUS_DISABLED 2
+
+/* SNMP value hack. */
+#define COUNTER ASN_COUNTER
+#define INTEGER ASN_INTEGER
+#define GAUGE ASN_GAUGE
+#define UNSIGNED ASN_UNSIGNED
+#define TIMETICKS ASN_TIMETICKS
+#define IPADDRESS ASN_IPADDRESS
+#define STRING ASN_OCTET_STR
+
+/* For return values e.g. SNMP_INTEGER macro */
+SNMP_LOCAL_VARIABLES
+
+/* OSPFv3-MIB instances. */
+static oid ospfv3_oid[] = {OSPFv3MIB};
+static oid ospfv3_trap_oid[] = {OSPFv3MIB, 0};
+
+/* Hook functions. */
+static uint8_t *ospfv3GeneralGroup(struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static uint8_t *ospfv3AreaEntry(struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static uint8_t *ospfv3WwLsdbEntry(struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static uint8_t *ospfv3NbrEntry(struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static uint8_t *ospfv3IfEntry(struct variable *, oid *, size_t *, int, size_t *,
+ WriteMethod **);
+
+static struct variable ospfv3_variables[] = {
+ /* OSPF general variables */
+ {OSPFv3ROUTERID, UNSIGNED, RWRITE, ospfv3GeneralGroup, 3, {1, 1, 1}},
+ {OSPFv3ADMINSTAT, INTEGER, RWRITE, ospfv3GeneralGroup, 3, {1, 1, 2}},
+ {OSPFv3VERSIONNUMBER, INTEGER, RONLY, ospfv3GeneralGroup, 3, {1, 1, 3}},
+ {OSPFv3AREABDRRTRSTATUS,
+ INTEGER,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 4}},
+ {OSPFv3ASBDRRTRSTATUS,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 5}},
+ {OSPFv3ASSCOPELSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, 3, {1, 1, 6}},
+ {OSPFv3ASSCOPELSACHECKSUMSUM,
+ UNSIGNED,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 7}},
+ {OSPFv3ORIGINATENEWLSAS,
+ COUNTER,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 8}},
+ {OSPFv3RXNEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup, 3, {1, 1, 9}},
+ {OSPFv3EXTLSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, 3, {1, 1, 10}},
+ {OSPFv3EXTAREALSDBLIMIT,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 11}},
+ {OSPFv3EXITOVERFLOWINTERVAL,
+ UNSIGNED,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 12}},
+ {OSPFv3DEMANDEXTENSIONS,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 13}},
+ {OSPFv3REFERENCEBANDWIDTH,
+ UNSIGNED,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 14}},
+ {OSPFv3RESTARTSUPPORT,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 15}},
+ {OSPFv3RESTARTINTERVAL,
+ UNSIGNED,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 16}},
+ {OSPFv3RESTARTSTRICTLSACHECKING,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 17}},
+ {OSPFv3RESTARTSTATUS,
+ INTEGER,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 18}},
+ {OSPFv3RESTARTAGE, UNSIGNED, RONLY, ospfv3GeneralGroup, 3, {1, 1, 19}},
+ {OSPFv3RESTARTEXITREASON,
+ INTEGER,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 20}},
+ {OSPFv3NOTIFICATIONENABLE,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 21}},
+ {OSPFv3STUBROUTERSUPPORT,
+ INTEGER,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 22}},
+ {OSPFv3STUBROUTERADVERTISEMENT,
+ INTEGER,
+ RWRITE,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 23}},
+ {OSPFv3DISCONTINUITYTIME,
+ TIMETICKS,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 24}},
+ {OSPFv3RESTARTTIME,
+ TIMETICKS,
+ RONLY,
+ ospfv3GeneralGroup,
+ 3,
+ {1, 1, 25}},
+
+ /* OSPFv3 Area Data Structure */
+ {OSPFv3IMPORTASEXTERN,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 2}},
+ {OSPFv3AREASPFRUNS, COUNTER, RONLY, ospfv3AreaEntry, 4, {1, 2, 1, 3}},
+ {OSPFv3AREABDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry, 4, {1, 2, 1, 4}},
+ {OSPFv3AREAASBDRRTRCOUNT,
+ GAUGE,
+ RONLY,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 5}},
+ {OSPFv3AREASCOPELSACOUNT,
+ GAUGE,
+ RONLY,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 6}},
+ {OSPFv3AREASCOPELSACKSUMSUM,
+ UNSIGNED,
+ RONLY,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 7}},
+ {OSPFv3AREASUMMARY, INTEGER, RWRITE, ospfv3AreaEntry, 4, {1, 2, 1, 8}},
+ {OSPFv3AREAROWSTATUS,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 9}},
+ {OSPFv3AREASTUBMETRIC,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 10}},
+ {OSPFv3AREANSSATRANSLATORROLE,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 11}},
+ {OSPFv3AREANSSATRANSLATORSTATE,
+ INTEGER,
+ RONLY,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 12}},
+ {OSPFv3AREANSSATRANSLATORSTABINTERVAL,
+ UNSIGNED,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 13}},
+ {OSPFv3AREANSSATRANSLATOREVENTS,
+ COUNTER,
+ RONLY,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 14}},
+ {OSPFv3AREASTUBMETRICTYPE,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 15}},
+ {OSPFv3AREATEENABLED,
+ INTEGER,
+ RWRITE,
+ ospfv3AreaEntry,
+ 4,
+ {1, 2, 1, 16}},
+
+ /* OSPFv3 AS LSDB */
+ {OSPFv3WWLSDBSEQUENCE | OSPFv3WWASTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 3, 1, 4}},
+ {OSPFv3WWLSDBAGE | OSPFv3WWASTABLE,
+ UNSIGNED,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 3, 1, 5}},
+ {OSPFv3WWLSDBCHECKSUM | OSPFv3WWASTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 3, 1, 6}},
+ {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWASTABLE,
+ STRING,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 3, 1, 7}},
+ {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWASTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 3, 1, 8}},
+
+ /* OSPFv3 Area LSDB */
+ {OSPFv3WWLSDBSEQUENCE | OSPFv3WWAREATABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 4, 1, 5}},
+ {OSPFv3WWLSDBAGE | OSPFv3WWAREATABLE,
+ UNSIGNED,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 4, 1, 6}},
+ {OSPFv3WWLSDBCHECKSUM | OSPFv3WWAREATABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 4, 1, 7}},
+ {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWAREATABLE,
+ STRING,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 4, 1, 8}},
+ {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWAREATABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 4, 1, 9}},
+
+ /* OSPFv3 Link LSDB */
+ {OSPFv3WWLSDBSEQUENCE | OSPFv3WWLINKTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 5, 1, 6}},
+ {OSPFv3WWLSDBAGE | OSPFv3WWLINKTABLE,
+ UNSIGNED,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 5, 1, 7}},
+ {OSPFv3WWLSDBCHECKSUM | OSPFv3WWLINKTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 5, 1, 8}},
+ {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWLINKTABLE,
+ STRING,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 5, 1, 9}},
+ {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWLINKTABLE,
+ INTEGER,
+ RONLY,
+ ospfv3WwLsdbEntry,
+ 4,
+ {1, 5, 1, 10}},
+
+ /* OSPFv3 interfaces */
+ {OSPFv3IFAREAID, UNSIGNED, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 3}},
+ {OSPFv3IFTYPE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 4}},
+ {OSPFv3IFADMINSTATUS, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 5}},
+ {OSPFv3IFRTRPRIORITY, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 6}},
+ {OSPFv3IFTRANSITDELAY, UNSIGNED, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 7}},
+ {OSPFv3IFRETRANSINTERVAL,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 8}},
+ {OSPFv3IFHELLOINTERVAL, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 9}},
+ {OSPFv3IFRTRDEADINTERVAL,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 10}},
+ {OSPFv3IFPOLLINTERVAL,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 11}},
+ {OSPFv3IFSTATE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 12}},
+ {OSPFv3IFDESIGNATEDROUTER,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 13}},
+ {OSPFv3IFBACKUPDESIGNATEDROUTER,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 14}},
+ {OSPFv3IFEVENTS, COUNTER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 15}},
+ {OSPFv3IFROWSTATUS, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 16}},
+ {OSPFv3IFDEMAND, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 17}},
+ {OSPFv3IFMETRICVALUE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 18}},
+ {OSPFv3IFLINKSCOPELSACOUNT,
+ GAUGE,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 19}},
+ {OSPFv3IFLINKLSACKSUMSUM,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 20}},
+ {OSPFv3IFDEMANDNBRPROBE,
+ INTEGER,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 21}},
+ {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 22}},
+ {OSPFv3IFDEMANDNBRPROBEINTERVAL,
+ UNSIGNED,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 23}},
+ {OSPFv3IFTEDISABLED, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 24}},
+ {OSPFv3IFLINKLSASUPPRESSION,
+ INTEGER,
+ RONLY,
+ ospfv3IfEntry,
+ 4,
+ {1, 7, 1, 25}},
+
+ /* OSPFv3 neighbors */
+ {OSPFv3NBRADDRESSTYPE, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 4}},
+ {OSPFv3NBRADDRESS, STRING, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 5}},
+ {OSPFv3NBROPTIONS, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 6}},
+ {OSPFv3NBRPRIORITY, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 7}},
+ {OSPFv3NBRSTATE, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 8}},
+ {OSPFv3NBREVENTS, COUNTER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 9}},
+ {OSPFv3NBRLSRETRANSQLEN,
+ GAUGE,
+ RONLY,
+ ospfv3NbrEntry,
+ 4,
+ {1, 9, 1, 10}},
+ {OSPFv3NBRHELLOSUPPRESSED,
+ INTEGER,
+ RONLY,
+ ospfv3NbrEntry,
+ 4,
+ {1, 9, 1, 11}},
+ {OSPFv3NBRIFID, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 12}},
+ {OSPFv3NBRRESTARTHELPERSTATUS,
+ INTEGER,
+ RONLY,
+ ospfv3NbrEntry,
+ 4,
+ {1, 9, 1, 13}},
+ {OSPFv3NBRRESTARTHELPERAGE,
+ UNSIGNED,
+ RONLY,
+ ospfv3NbrEntry,
+ 4,
+ {1, 9, 1, 14}},
+ {OSPFv3NBRRESTARTHELPEREXITREASON,
+ INTEGER,
+ RONLY,
+ ospfv3NbrEntry,
+ 4,
+ {1, 9, 1, 15}},
+};
+
+static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name,
+ size_t *length, int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ uint16_t sum;
+ uint32_t count;
+ struct ospf6_lsa *lsa = NULL, *lsanext;
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic) {
+ case OSPFv3ROUTERID:
+ /* Router-ID of this OSPF instance. */
+ if (ospf6)
+ return SNMP_INTEGER(ntohl(ospf6->router_id));
+ return SNMP_INTEGER(0);
+ case OSPFv3ADMINSTAT:
+ if (ospf6)
+ return SNMP_INTEGER(
+ CHECK_FLAG(ospf6->flag, OSPF6_DISABLED)
+ ? OSPF_STATUS_DISABLED
+ : OSPF_STATUS_ENABLED);
+ return SNMP_INTEGER(OSPF_STATUS_DISABLED);
+ case OSPFv3VERSIONNUMBER:
+ return SNMP_INTEGER(3);
+ case OSPFv3AREABDRRTRSTATUS:
+ if (ospf6)
+ return SNMP_INTEGER(
+ ospf6_check_and_set_router_abr(ospf6)
+ ? SNMP_TRUE
+ : SNMP_FALSE);
+ return SNMP_INTEGER(SNMP_FALSE);
+ case OSPFv3ASBDRRTRSTATUS:
+ if (ospf6)
+ return SNMP_INTEGER(ospf6_asbr_is_asbr(ospf6)
+ ? SNMP_TRUE
+ : SNMP_FALSE);
+ return SNMP_INTEGER(SNMP_FALSE);
+ case OSPFv3ASSCOPELSACOUNT:
+ if (ospf6)
+ return SNMP_INTEGER(ospf6->lsdb->count);
+ return SNMP_INTEGER(0);
+ case OSPFv3ASSCOPELSACHECKSUMSUM:
+ if (ospf6) {
+ sum = 0;
+ for (ALL_LSDB(ospf6->lsdb, lsa, lsanext))
+ sum += ntohs(lsa->header->checksum);
+ return SNMP_INTEGER(sum);
+ }
+ return SNMP_INTEGER(0);
+ case OSPFv3ORIGINATENEWLSAS:
+ return SNMP_INTEGER(
+ 0); /* Don't know where to get this value... */
+ case OSPFv3RXNEWLSAS:
+ return SNMP_INTEGER(
+ 0); /* Don't know where to get this value... */
+ case OSPFv3EXTLSACOUNT:
+ if (ospf6) {
+ count = 0;
+ for (ALL_LSDB_TYPED(ospf6->lsdb,
+ htons(OSPF6_LSTYPE_AS_EXTERNAL),
+ lsa))
+ count += 1;
+ return SNMP_INTEGER(count);
+ }
+ return SNMP_INTEGER(0);
+ case OSPFv3EXTAREALSDBLIMIT:
+ return SNMP_INTEGER(-1);
+ case OSPFv3EXITOVERFLOWINTERVAL:
+ return SNMP_INTEGER(0); /* Not supported */
+ case OSPFv3DEMANDEXTENSIONS:
+ return SNMP_INTEGER(0); /* Not supported */
+ case OSPFv3REFERENCEBANDWIDTH:
+ if (ospf6)
+ return SNMP_INTEGER(ospf6->ref_bandwidth);
+ /* Otherwise, like for "not implemented". */
+ /* fallthru */
+ case OSPFv3RESTARTSUPPORT:
+ case OSPFv3RESTARTINTERVAL:
+ case OSPFv3RESTARTSTRICTLSACHECKING:
+ case OSPFv3RESTARTSTATUS:
+ case OSPFv3RESTARTAGE:
+ case OSPFv3RESTARTEXITREASON:
+ case OSPFv3NOTIFICATIONENABLE:
+ case OSPFv3STUBROUTERSUPPORT:
+ case OSPFv3STUBROUTERADVERTISEMENT:
+ case OSPFv3DISCONTINUITYTIME:
+ case OSPFv3RESTARTTIME:
+ /* TODO: Not implemented */
+ return NULL;
+ }
+ return NULL;
+}
+
+static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ struct ospf6_area *oa, *area = NULL;
+ struct ospf6_lsa *lsa = NULL, *lsanext;
+ uint32_t area_id = 0;
+ uint32_t count;
+ uint16_t sum;
+ struct listnode *node;
+ unsigned int len;
+ char a[16];
+ struct ospf6_route *ro;
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
+
+ if (ospf6 == NULL)
+ return NULL;
+
+ if (smux_header_table(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ len = *length - v->namelen;
+ len = (len >= 1 ? 1 : 0);
+ if (exact && len != 1)
+ return NULL;
+ if (len)
+ area_id = htonl(name[v->namelen]);
+
+ inet_ntop(AF_INET, &area_id, a, sizeof(a));
+ zlog_debug("SNMP access by area: %s, exact=%d len=%d length=%lu", a,
+ exact, len, (unsigned long)*length);
+
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
+ if (area == NULL) {
+ if (len == 0) /* return first area entry */
+ area = oa;
+ else if (exact && ntohl(oa->area_id) == ntohl(area_id))
+ area = oa;
+ else if (ntohl(oa->area_id) > ntohl(area_id))
+ area = oa;
+ }
+ }
+
+ if (area == NULL)
+ return NULL;
+
+ *length = v->namelen + 1;
+ name[v->namelen] = ntohl(area->area_id);
+
+ inet_ntop(AF_INET, &area->area_id, a, sizeof(a));
+ zlog_debug("SNMP found area: %s, exact=%d len=%d length=%lu", a, exact,
+ len, (unsigned long)*length);
+
+ switch (v->magic) {
+ case OSPFv3IMPORTASEXTERN:
+ /* No NSSA support */
+ return SNMP_INTEGER(IS_AREA_STUB(area) ? 2 : 1);
+ case OSPFv3AREASPFRUNS:
+ return SNMP_INTEGER(area->spf_calculation);
+ case OSPFv3AREABDRRTRCOUNT:
+ case OSPFv3AREAASBDRRTRCOUNT:
+ count = 0;
+ for (ro = ospf6_route_head(ospf6->brouter_table); ro;
+ ro = ospf6_route_next(ro)) {
+ if (ntohl(ro->path.area_id) != ntohl(area->area_id))
+ continue;
+ if (v->magic == OSPFv3AREABDRRTRCOUNT
+ && CHECK_FLAG(ro->path.router_bits,
+ OSPF6_ROUTER_BIT_B))
+ count++;
+ if (v->magic == OSPFv3AREAASBDRRTRCOUNT
+ && CHECK_FLAG(ro->path.router_bits,
+ OSPF6_ROUTER_BIT_E))
+ count++;
+ }
+ return SNMP_INTEGER(count);
+ case OSPFv3AREASCOPELSACOUNT:
+ return SNMP_INTEGER(area->lsdb->count);
+ case OSPFv3AREASCOPELSACKSUMSUM:
+ sum = 0;
+ for (ALL_LSDB(area->lsdb, lsa, lsanext))
+ sum += ntohs(lsa->header->checksum);
+ return SNMP_INTEGER(sum);
+ case OSPFv3AREASUMMARY:
+ return SNMP_INTEGER(2); /* sendAreaSummary */
+ case OSPFv3AREAROWSTATUS:
+ return SNMP_INTEGER(1); /* Active */
+ case OSPFv3AREASTUBMETRIC:
+ case OSPFv3AREANSSATRANSLATORROLE:
+ case OSPFv3AREANSSATRANSLATORSTATE:
+ case OSPFv3AREANSSATRANSLATORSTABINTERVAL:
+ case OSPFv3AREANSSATRANSLATOREVENTS:
+ case OSPFv3AREASTUBMETRICTYPE:
+ case OSPFv3AREATEENABLED:
+ /* Not implemented. */
+ return NULL;
+ }
+ return NULL;
+}
+
+static int if_icmp_func(struct interface *ifp1, struct interface *ifp2)
+{
+ return (ifp1->ifindex - ifp2->ifindex);
+}
+
+static uint8_t *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ struct vrf *vrf;
+ struct ospf6_lsa *lsa = NULL;
+ ifindex_t ifindex;
+ uint32_t area_id, id, instid, adv_router;
+ uint16_t type;
+ int len;
+ oid *offset;
+ int offsetlen;
+ struct ospf6_area *oa = NULL;
+ struct listnode *node;
+ struct interface *iif;
+ struct ospf6_interface *oi = NULL;
+ struct list *ifslist;
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
+
+ if (smux_header_table(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ instid = ifindex = area_id = type = id = adv_router = 0;
+
+ /* Check OSPFv3 instance. */
+ if (ospf6 == NULL)
+ return NULL;
+
+ vrf = vrf_lookup_by_id(ospf6->vrf_id);
+ /* Get variable length. */
+ offset = name + v->namelen;
+ offsetlen = *length - v->namelen;
+
+ if (exact && (v->magic & OSPFv3WWASTABLE) && offsetlen != 3)
+ return NULL;
+ if (exact && (v->magic & OSPFv3WWAREATABLE) && offsetlen != 4)
+ return NULL;
+ if (exact && (v->magic & OSPFv3WWLINKTABLE) && offsetlen != 5)
+ return NULL;
+
+ if (v->magic & OSPFv3WWLINKTABLE) {
+ /* Parse ifindex */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ ifindex = *offset;
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse instance ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ instid = *offset;
+ offset += len;
+ offsetlen -= len;
+ } else if (v->magic & OSPFv3WWAREATABLE) {
+ /* Parse area-id */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ area_id = htonl(*offset);
+ offset += len;
+ offsetlen -= len;
+ }
+
+ /* Parse type */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ type = htons(*offset);
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse Router-ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ adv_router = htonl(*offset);
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse LS-ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ id = htonl(*offset);
+ offset += len;
+ // offsetlen -= len; // Add back in if we need it again
+
+ if (exact) {
+ if (v->magic & OSPFv3WWASTABLE) {
+ lsa = ospf6_lsdb_lookup(type, id, adv_router,
+ ospf6->lsdb);
+ } else if (v->magic & OSPFv3WWAREATABLE) {
+ oa = ospf6_area_lookup(area_id, ospf6);
+ if (!oa)
+ return NULL;
+ lsa = ospf6_lsdb_lookup(type, id, adv_router, oa->lsdb);
+ } else if (v->magic & OSPFv3WWLINKTABLE) {
+ oi = ospf6_interface_lookup_by_ifindex(ifindex,
+ ospf6->vrf_id);
+ if (!oi || oi->instance_id != instid)
+ return NULL;
+ lsa = ospf6_lsdb_lookup(type, id, adv_router, oi->lsdb);
+ }
+ } else {
+ if (v->magic & OSPFv3WWASTABLE) {
+ if (ospf6->lsdb->count)
+ lsa = ospf6_lsdb_lookup_next(
+ type, id, adv_router, ospf6->lsdb);
+ } else if (v->magic & OSPFv3WWAREATABLE)
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
+ if (oa->area_id < area_id)
+ continue;
+
+ if (oa->lsdb->count)
+ lsa = ospf6_lsdb_lookup_next(
+ type, id, adv_router, oa->lsdb);
+ if (lsa)
+ break;
+ type = 0;
+ id = 0;
+ adv_router = 0;
+ }
+ else if (v->magic & OSPFv3WWLINKTABLE) {
+ /* We build a sorted list of interfaces */
+ ifslist = list_new();
+ ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
+ FOR_ALL_INTERFACES (vrf, iif)
+ listnode_add_sort(ifslist, iif);
+
+ for (ALL_LIST_ELEMENTS_RO(ifslist, node, iif)) {
+ if (!iif->ifindex)
+ continue;
+ oi = iif->info;
+ if (!oi)
+ continue;
+ if (iif->ifindex < ifindex)
+ continue;
+ if (oi->instance_id < instid)
+ continue;
+
+ if (oi->lsdb->count)
+ lsa = ospf6_lsdb_lookup_next(
+ type, id, adv_router, oi->lsdb);
+ if (lsa)
+ break;
+ type = 0;
+ id = 0;
+ adv_router = 0;
+ oi = NULL;
+ }
+
+ list_delete_all_node(ifslist);
+ list_delete(&ifslist);
+ }
+ }
+
+ if (!lsa)
+ return NULL;
+
+ /* Add indexes */
+ if (v->magic & OSPFv3WWASTABLE) {
+ *length = v->namelen + 3;
+ offset = name + v->namelen;
+ } else if (v->magic & OSPFv3WWAREATABLE) {
+ *length = v->namelen + 4;
+ offset = name + v->namelen;
+ *offset = ntohl(oa->area_id);
+ offset++;
+ } else if (v->magic & OSPFv3WWLINKTABLE) {
+ *length = v->namelen + 5;
+ offset = name + v->namelen;
+ *offset = oi->interface->ifindex;
+ offset++;
+ *offset = oi->instance_id;
+ offset++;
+ }
+ *offset = ntohs(lsa->header->type);
+ offset++;
+ *offset = ntohl(lsa->header->adv_router);
+ offset++;
+ *offset = ntohl(lsa->header->id);
+ offset++;
+
+ /* Return the current value of the variable */
+ switch (v->magic & OSPFv3WWCOLUMN) {
+ case OSPFv3WWLSDBSEQUENCE:
+ return SNMP_INTEGER(ntohl(lsa->header->seqnum));
+ case OSPFv3WWLSDBAGE:
+ ospf6_lsa_age_current(lsa);
+ return SNMP_INTEGER(ntohs(lsa->header->age));
+ case OSPFv3WWLSDBCHECKSUM:
+ return SNMP_INTEGER(ntohs(lsa->header->checksum));
+ case OSPFv3WWLSDBADVERTISEMENT:
+ *var_len = ntohs(lsa->header->length);
+ return (uint8_t *)lsa->header;
+ case OSPFv3WWLSDBTYPEKNOWN:
+ return SNMP_INTEGER(OSPF6_LSA_IS_KNOWN(lsa->header->type)
+ ? SNMP_TRUE
+ : SNMP_FALSE);
+ }
+ return NULL;
+}
+
+static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ struct vrf *vrf;
+ ifindex_t ifindex = 0;
+ unsigned int instid = 0;
+ struct ospf6_interface *oi = NULL;
+ struct ospf6_lsa *lsa = NULL, *lsanext;
+ struct interface *iif;
+ struct listnode *i;
+ struct list *ifslist;
+ oid *offset;
+ int offsetlen, len;
+ uint32_t sum;
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
+
+ if (smux_header_table(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Check OSPFv3 instance. */
+ if (ospf6 == NULL)
+ return NULL;
+
+ vrf = vrf_lookup_by_id(ospf6->vrf_id);
+ /* Get variable length. */
+ offset = name + v->namelen;
+ offsetlen = *length - v->namelen;
+
+ if (exact && offsetlen != 2)
+ return NULL;
+
+ /* Parse if index */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ ifindex = *offset;
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse instance ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ instid = *offset;
+ // offset += len; // Add back in if we ever start using again
+ // offsetlen -= len;
+
+ if (exact) {
+ oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
+ if (!oi || oi->instance_id != instid)
+ return NULL;
+ } else {
+ /* We build a sorted list of interfaces */
+ ifslist = list_new();
+ ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
+ FOR_ALL_INTERFACES (vrf, iif)
+ listnode_add_sort(ifslist, iif);
+
+ for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) {
+ if (!iif->ifindex)
+ continue;
+ oi = iif->info;
+ if (!oi)
+ continue;
+ if (iif->ifindex > ifindex
+ || (iif->ifindex == ifindex
+ && (oi->instance_id > instid)))
+ break;
+ oi = NULL;
+ }
+
+ list_delete_all_node(ifslist);
+ list_delete(&ifslist);
+ }
+
+ if (!oi)
+ return NULL;
+
+ /* Add Index (IfIndex, IfInstId) */
+ *length = v->namelen + 2;
+ offset = name + v->namelen;
+ *offset = oi->interface->ifindex;
+ offset++;
+ *offset = oi->instance_id;
+ offset++;
+
+ /* Return the current value of the variable */
+ switch (v->magic) {
+ case OSPFv3IFAREAID:
+ if (oi->area)
+ return SNMP_INTEGER(ntohl(oi->area->area_id));
+ break;
+ case OSPFv3IFTYPE:
+ if (oi->type == OSPF_IFTYPE_BROADCAST)
+ return SNMP_INTEGER(1);
+ else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ return SNMP_INTEGER(3);
+ else
+ break; /* Unknown, don't put anything */
+ case OSPFv3IFADMINSTATUS:
+ if (oi->area)
+ return SNMP_INTEGER(OSPF_STATUS_ENABLED);
+ return SNMP_INTEGER(OSPF_STATUS_DISABLED);
+ case OSPFv3IFRTRPRIORITY:
+ return SNMP_INTEGER(oi->priority);
+ case OSPFv3IFTRANSITDELAY:
+ return SNMP_INTEGER(oi->transdelay);
+ case OSPFv3IFRETRANSINTERVAL:
+ return SNMP_INTEGER(oi->rxmt_interval);
+ case OSPFv3IFHELLOINTERVAL:
+ return SNMP_INTEGER(oi->hello_interval);
+ case OSPFv3IFRTRDEADINTERVAL:
+ return SNMP_INTEGER(oi->dead_interval);
+ case OSPFv3IFPOLLINTERVAL:
+ /* No support for NBMA */
+ break;
+ case OSPFv3IFSTATE:
+ return SNMP_INTEGER(oi->state);
+ case OSPFv3IFDESIGNATEDROUTER:
+ return SNMP_INTEGER(ntohl(oi->drouter));
+ case OSPFv3IFBACKUPDESIGNATEDROUTER:
+ return SNMP_INTEGER(ntohl(oi->bdrouter));
+ case OSPFv3IFEVENTS:
+ return SNMP_INTEGER(oi->state_change);
+ case OSPFv3IFROWSTATUS:
+ return SNMP_INTEGER(1);
+ case OSPFv3IFDEMAND:
+ return SNMP_INTEGER(SNMP_FALSE);
+ case OSPFv3IFMETRICVALUE:
+ return SNMP_INTEGER(oi->cost);
+ case OSPFv3IFLINKSCOPELSACOUNT:
+ return SNMP_INTEGER(oi->lsdb->count);
+ case OSPFv3IFLINKLSACKSUMSUM:
+ sum = 0;
+ for (ALL_LSDB(oi->lsdb, lsa, lsanext))
+ sum += ntohs(lsa->header->checksum);
+ return SNMP_INTEGER(sum);
+ case OSPFv3IFDEMANDNBRPROBE:
+ case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT:
+ case OSPFv3IFDEMANDNBRPROBEINTERVAL:
+ case OSPFv3IFTEDISABLED:
+ case OSPFv3IFLINKLSASUPPRESSION:
+ /* Not implemented. Only works if all the last ones are not
+ implemented! */
+ return NULL;
+ }
+
+ /* Try an internal getnext. Some columns are missing in this table. */
+ if (!exact && (name[*length - 1] < MAX_SUBID))
+ return ospfv3IfEntry(v, name, length, exact, var_len,
+ write_method);
+ return NULL;
+}
+
+static uint8_t *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ struct vrf *vrf;
+ ifindex_t ifindex = 0;
+ unsigned int instid, rtrid;
+ struct ospf6_interface *oi = NULL;
+ struct ospf6_neighbor *on = NULL;
+ struct interface *iif;
+ struct listnode *i, *j;
+ struct list *ifslist;
+ oid *offset;
+ int offsetlen, len;
+ struct ospf6 *ospf6;
+
+ ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
+
+ if (smux_header_table(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ instid = rtrid = 0;
+
+ /* Check OSPFv3 instance. */
+ if (ospf6 == NULL)
+ return NULL;
+
+ vrf = vrf_lookup_by_id(ospf6->vrf_id);
+ /* Get variable length. */
+ offset = name + v->namelen;
+ offsetlen = *length - v->namelen;
+
+ if (exact && offsetlen != 3)
+ return NULL;
+
+ /* Parse if index */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ ifindex = *offset;
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse instance ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ instid = *offset;
+ offset += len;
+ offsetlen -= len;
+
+ /* Parse router ID */
+ len = (offsetlen < 1 ? 0 : 1);
+ if (len)
+ rtrid = htonl(*offset);
+ // offset += len; // Add back in if we ever start looking at data
+ // offsetlen -= len;
+
+ if (exact) {
+ oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
+ if (!oi || oi->instance_id != instid)
+ return NULL;
+ on = ospf6_neighbor_lookup(rtrid, oi);
+ } else {
+ /* We build a sorted list of interfaces */
+ ifslist = list_new();
+ ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
+ FOR_ALL_INTERFACES (vrf, iif)
+ listnode_add_sort(ifslist, iif);
+
+ for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) {
+ if (!iif->ifindex)
+ continue;
+ oi = iif->info;
+ if (!oi)
+ continue;
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) {
+ if (iif->ifindex > ifindex
+ || (iif->ifindex == ifindex
+ && (oi->instance_id > instid
+ || (oi->instance_id == instid
+ && ntohl(on->router_id)
+ > ntohl(rtrid)))))
+ break;
+ }
+ if (on)
+ break;
+ oi = NULL;
+ on = NULL;
+ }
+
+ list_delete_all_node(ifslist);
+ list_delete(&ifslist);
+ }
+
+ if (!oi || !on)
+ return NULL;
+
+ /* Add Index (IfIndex, IfInstId, RtrId) */
+ *length = v->namelen + 3;
+ offset = name + v->namelen;
+ *offset = oi->interface->ifindex;
+ offset++;
+ *offset = oi->instance_id;
+ offset++;
+ *offset = ntohl(on->router_id);
+ offset++;
+
+ /* Return the current value of the variable */
+ switch (v->magic) {
+ case OSPFv3NBRADDRESSTYPE:
+ return SNMP_INTEGER(2); /* IPv6 only */
+ case OSPFv3NBRADDRESS:
+ *var_len = sizeof(struct in6_addr);
+ return (uint8_t *)&on->linklocal_addr;
+ case OSPFv3NBROPTIONS:
+ return SNMP_INTEGER(on->options[2]);
+ case OSPFv3NBRPRIORITY:
+ return SNMP_INTEGER(on->priority);
+ case OSPFv3NBRSTATE:
+ return SNMP_INTEGER(on->state);
+ case OSPFv3NBREVENTS:
+ return SNMP_INTEGER(on->state_change);
+ case OSPFv3NBRLSRETRANSQLEN:
+ return SNMP_INTEGER(on->retrans_list->count);
+ case OSPFv3NBRHELLOSUPPRESSED:
+ return SNMP_INTEGER(SNMP_FALSE);
+ case OSPFv3NBRIFID:
+ return SNMP_INTEGER(on->ifindex);
+ case OSPFv3NBRRESTARTHELPERSTATUS:
+ case OSPFv3NBRRESTARTHELPERAGE:
+ case OSPFv3NBRRESTARTHELPEREXITREASON:
+ /* Not implemented. Only works if all the last ones are not
+ implemented! */
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/* OSPF Traps. */
+#define NBRSTATECHANGE 2
+#define IFSTATECHANGE 10
+
+static struct trap_object ospf6NbrTrapList[] = {
+ {-3, {1, 1, OSPFv3ROUTERID}},
+ {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE}},
+ {4, {1, 9, 1, OSPFv3NBRADDRESS}},
+ {4, {1, 9, 1, OSPFv3NBRSTATE}}};
+
+static struct trap_object ospf6IfTrapList[] = {
+ {-3, {1, 1, OSPFv3ROUTERID}},
+ {4, {1, 7, 1, OSPFv3IFSTATE}},
+ {4, {1, 7, 1, OSPFv3IFADMINSTATUS}},
+ {4, {1, 7, 1, OSPFv3IFAREAID}}};
+
+static int ospf6TrapNbrStateChange(struct ospf6_neighbor *on, int next_state,
+ int prev_state)
+{
+ oid index[3];
+
+ /* Terminal state or regression */
+ if ((next_state != OSPF6_NEIGHBOR_FULL)
+ && (next_state != OSPF6_NEIGHBOR_TWOWAY)
+ && (next_state >= prev_state))
+ return 0;
+
+ index[0] = on->ospf6_if->interface->ifindex;
+ index[1] = on->ospf6_if->instance_id;
+ index[2] = ntohl(on->router_id);
+
+ smux_trap(ospfv3_variables, array_size(ospfv3_variables),
+ ospfv3_trap_oid, array_size(ospfv3_trap_oid), ospfv3_oid,
+ sizeof(ospfv3_oid) / sizeof(oid), index, 3, ospf6NbrTrapList,
+ array_size(ospf6NbrTrapList), NBRSTATECHANGE);
+ return 0;
+}
+
+static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state,
+ int prev_state)
+{
+ oid index[2];
+
+ /* Terminal state or regression */
+ if ((next_state != OSPF6_INTERFACE_POINTTOPOINT)
+ && (next_state != OSPF6_INTERFACE_DROTHER)
+ && (next_state != OSPF6_INTERFACE_BDR)
+ && (next_state != OSPF6_INTERFACE_DR) && (next_state >= prev_state))
+ return 0;
+
+ index[0] = oi->interface->ifindex;
+ index[1] = oi->instance_id;
+
+ smux_trap(ospfv3_variables, array_size(ospfv3_variables),
+ ospfv3_trap_oid, array_size(ospfv3_trap_oid), ospfv3_oid,
+ sizeof(ospfv3_oid) / sizeof(oid), index, 2, ospf6IfTrapList,
+ array_size(ospf6IfTrapList), IFSTATECHANGE);
+ return 0;
+}
+
+/* Register OSPFv3-MIB. */
+static int ospf6_snmp_init(struct event_loop *master)
+{
+ smux_init(master);
+ REGISTER_MIB("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
+ return 0;
+}
+
+static int ospf6_snmp_module_init(void)
+{
+ hook_register(ospf6_interface_change, ospf6TrapIfStateChange);
+ hook_register(ospf6_neighbor_change, ospf6TrapNbrStateChange);
+ hook_register(frr_late_init, ospf6_snmp_init);
+ return 0;
+}
+
+FRR_MODULE_SETUP(.name = "ospf6d_snmp", .version = FRR_VERSION,
+ .description = "ospf6d AgentX SNMP module",
+ .init = ospf6_snmp_module_init,
+);