summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospf6d/ospf6_interface.c1
-rw-r--r--ospf6d/ospf6_interface.h2
-rw-r--r--ospf6d/ospf6_snmp.c204
3 files changed, 206 insertions, 1 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 71aa6859..6f7aaa8a 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -394,6 +394,7 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
ospf6_interface_state_str[prev_state],
ospf6_interface_state_str[next_state]);
}
+ oi->state_change++;
if ((prev_state == OSPF6_INTERFACE_DR ||
prev_state == OSPF6_INTERFACE_BDR) &&
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 2d1ff34d..d80b0730 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -64,6 +64,8 @@ struct ospf6_interface
u_int16_t dead_interval;
u_int32_t rxmt_interval;
+ u_int32_t state_change;
+
/* Cost */
u_int32_t cost;
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index 293d66a1..1880fc0a 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -227,6 +227,8 @@ static u_char *ospfv3AreaLsdbEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **);
static u_char *ospfv3NbrEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **);
+static u_char *ospfv3IfEntry (struct variable *, oid *, size_t *,
+ int, size_t *, WriteMethod **);
struct variable ospfv3_variables[] =
{
@@ -326,6 +328,54 @@ struct variable ospfv3_variables[] =
{OSPFv3AREALSDBTYPEKNOWN, INTEGER, RONLY, ospfv3AreaLsdbEntry,
4, {1, 4, 1, 9}},
+ /* 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}},
@@ -692,6 +742,159 @@ if_icmp_func (struct interface *ifp1, struct interface *ifp2)
}
static u_char *
+ospfv3IfEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ unsigned int ifindex, instid;
+ struct ospf6_interface *oi = NULL;
+ struct ospf6_lsa *lsa = NULL;
+ struct interface *iif;
+ struct listnode *i;
+ struct list *ifslist;
+ oid *offset;
+ int offsetlen, len;
+ u_int32_t sum;
+
+ if (smux_header_table (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ ifindex = instid = 0;
+
+ /* Check OSPFv3 instance. */
+ if (ospf6 == NULL)
+ return NULL;
+
+ /* 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;
+ offsetlen -= len;
+
+ if (exact)
+ {
+ oi = ospf6_interface_lookup_by_ifindex (ifindex);
+ if (oi->instance_id != instid) return NULL;
+ }
+ else
+ {
+ /* We build a sorted list of interfaces */
+ ifslist = list_new ();
+ if (!ifslist) return NULL;
+ ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
+ for (ALL_LIST_ELEMENTS_RO (iflist, i, iif))
+ listnode_add_sort (ifslist, iif);
+
+ for (ALL_LIST_ELEMENTS_RO (ifslist, i, iif))
+ {
+ if (!iif->ifindex) continue;
+ oi = ospf6_interface_lookup_by_ifindex (iif->ifindex);
+ if (!oi) continue;
+ if (iif->ifindex > ifindex ||
+ (iif->ifindex == ifindex &&
+ (oi->instance_id > instid)))
+ break;
+ oi = NULL;
+ }
+
+ list_delete_all_node (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 (if_is_broadcast (oi->interface))
+ return SNMP_INTEGER (1);
+ else if (if_is_pointopoint (oi->interface))
+ 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:
+ for (sum = 0, lsa = ospf6_lsdb_head (oi->lsdb);
+ lsa;
+ lsa = ospf6_lsdb_next (lsa))
+ 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 u_char *
ospfv3NbrEntry (struct variable *v, oid *name, size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
@@ -822,7 +1025,6 @@ ospfv3NbrEntry (struct variable *v, oid *name, size_t *length,
return NULL;
}
-
/* Register OSPFv3-MIB. */
void
ospf6_snmp_init (struct thread_master *master)