summaryrefslogtreecommitdiff
path: root/ospf6d
diff options
context:
space:
mode:
authorVincent Bernat <bernat@luffy.cx>2012-05-31 20:21:15 +0200
committerVincent Bernat <bernat@luffy.cx>2012-06-25 19:05:16 +0200
commit061bc735b4fb3b8768fa5f52295d85838ed55770 (patch)
tree80f74a55bfbd93d9111d5b49676bcea11a91285e /ospf6d
parent0f0ab5180877559e92b71daacb8a106a815a5ade (diff)
ospf6d: add SNMP support for ospfv3NbrTable
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_neighbor.c2
-rw-r--r--ospf6d/ospf6_neighbor.h1
-rw-r--r--ospf6d/ospf6_snmp.c164
3 files changed, 167 insertions, 0 deletions
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index f6c3aeac..ab157ca8 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -89,6 +89,7 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
buf, oi->interface->name);
on->ospf6_if = oi;
on->state = OSPF6_NEIGHBOR_DOWN;
+ on->state_change = 0;
quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
on->router_id = router_id;
@@ -154,6 +155,7 @@ ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
if (prev_state == next_state)
return;
+ on->state_change++;
quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
/* log */
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index b3bd173f..5f46c6f3 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -46,6 +46,7 @@ struct ospf6_neighbor
u_char state;
/* timestamp of last changing state */
+ u_int32_t state_change;
struct timeval last_changed;
/* Neighbor Router ID */
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index 95b4fc08..5e4ca0f6 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -225,6 +225,8 @@ static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **);
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 **);
struct variable ospfv3_variables[] =
{
@@ -324,6 +326,31 @@ struct variable ospfv3_variables[] =
{OSPFv3AREALSDBTYPEKNOWN, INTEGER, RONLY, ospfv3AreaLsdbEntry,
4, {1, 4, 1, 9}},
+ /* 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 u_char *
@@ -588,6 +615,143 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
return NULL;
}
+static int
+if_icmp_func (struct interface *ifp1, struct interface *ifp2)
+{
+ return (ifp1->ifindex - ifp2->ifindex);
+}
+
+static u_char *
+ospfv3NbrEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ unsigned int ifindex, 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;
+
+ if (smux_header_table (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ ifindex = instid = rtrid = 0;
+
+ /* Check OSPFv3 instance. */
+ if (ospf6 == NULL)
+ return NULL;
+
+ /* 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;
+ offsetlen -= len;
+
+ if (exact)
+ {
+ oi = ospf6_interface_lookup_by_ifindex (ifindex);
+ on = ospf6_neighbor_lookup (rtrid, oi);
+ 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;
+ 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 = on = NULL;
+ }
+
+ list_delete_all_node (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 (u_char *) &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;
+}
+
/* Register OSPFv3-MIB. */
void