]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: add SNMP implementation of ospfv3IfTable
authorVincent Bernat <bernat@luffy.cx>
Mon, 4 Jun 2012 09:40:04 +0000 (11:40 +0200)
committerVincent Bernat <bernat@luffy.cx>
Mon, 25 Jun 2012 17:05:17 +0000 (19:05 +0200)
ospf6d/ospf6_interface.c
ospf6d/ospf6_interface.h
ospf6d/ospf6_snmp.c

index 71aa6859c78aa801273effbac5cc3dad90e45cc5..6f7aaa8af2174d4e403cf35a81a52c8a2c4d0037 100644 (file)
@@ -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) &&
index 2d1ff34dbede2627b4435f015e507fb219163700..d80b073035822b8e1039dd59eab5d83ecbb292bf 100644 (file)
@@ -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;
 
index 293d66a12a9d4f2f1d3af21c2294527a06689da5..1880fc0a3a3342d25b8cfbd5cb21f9306cc5c5d5 100644 (file)
@@ -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}},
@@ -691,6 +741,159 @@ if_icmp_func (struct interface *ifp1, struct interface *ifp2)
   return (ifp1->ifindex - ifp2->ifindex);
 }
 
+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)