2005-10-06 Alain Ritoux <alain.ritoux@6wind.com>

* ospf_snmp.c: Avoid mixing interface and ospf_interface objects
          which now allows snmpwalk to work with ospfIfTable and
          also with ospfIfMetricTable
This commit is contained in:
vincent 2005-10-06 07:46:22 +00:00
parent fac3e8410a
commit 77df1f7859
2 changed files with 109 additions and 58 deletions

View File

@ -1,3 +1,9 @@
2005-10-06 Alain Ritoux <alain.ritoux@6wind.com>
* ospf_snmp.c: Avoid mixing interface and ospf_interface objects
which now allows snmpwalk to work with ospfIfTable and
also with ospfIfMetricTable
2005-10-01 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* ospf_dump.c: Remove local hard-coded table ospf_redistributed_proto.

View File

@ -1458,12 +1458,13 @@ ospf_snmp_if_update (struct interface *ifp)
{
if (addr)
{
/* Usual interfaces --> Sort them based on interface IPv4 addresses */
if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
break;
}
else
{
/* Unnumbered interface. */
/* Unnumbered interfaces --> Sort them based on interface indexes */
if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
break;
}
@ -1471,76 +1472,130 @@ ospf_snmp_if_update (struct interface *ifp)
}
osif = ospf_snmp_if_new ();
if (addr)
if (addr) /* Usual interface */
{
osif->addr = *addr;
else
/* This field is used for storing ospfAddressLessIf OID value,
* conform to RFC1850 OSPF-MIB specification, it must be 0 for
* usual interface */
osif->ifindex = 0;
}
else /* Unnumbered interface */
osif->ifindex = ifindex;
osif->ifp = ifp;
listnode_add_after (ospf_snmp_iflist, pn, osif);
}
struct interface *
int
ospf_snmp_is_if_have_addr (struct interface *ifp)
{
struct prefix *p;
struct listnode *nn;
struct connected *ifc;
/* Is this interface having any connected IPv4 address ? */
for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
{
if (if_is_pointopoint (ifp))
p = ifc->destination;
else
p = ifc->address;
if (p->family == AF_INET)
return 1;
}
return 0;
}
struct ospf_interface *
ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
{
struct listnode *node;
struct ospf_snmp_if *osif;
struct ospf_interface *oi = NULL;
struct ospf *ospf = ospf_lookup ();
for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
{
if (ifaddr->s_addr)
{
if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
return osif->ifp;
oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
}
else
{
if (osif->ifindex == *ifindex)
return osif->ifp;
oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
}
}
return NULL;
return oi;
}
struct interface *
struct ospf_interface *
ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
int ifaddr_next, int ifindex_next)
{
struct ospf_snmp_if *osif;
struct listnode *nn;
struct ospf *ospf = ospf_lookup ();
struct ospf_interface *oi = NULL;
if (ospf == NULL)
return NULL;
/* No instance is specified --> Return the first OSPF interface */
if (ifaddr_next)
{
nn = listhead (ospf_snmp_iflist);
if (nn)
for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
{
osif = listgetdata (nn);
*ifaddr = osif->addr;
*ifindex = osif->ifindex;
return osif->ifp;
/* Because no instance is specified, we don't care about the kind of
* interface (usual or unnumbered), just returning the first valid
* OSPF interface */
oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
if (oi)
return (oi);
}
return NULL;
}
/* An instance is specified --> Return the next OSPF interface */
for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
{
/* Usual interface */
if (ifaddr->s_addr)
{
if (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr))
/* The interface must have valid AF_INET connected address */
/* it must have lager IPv4 address value than the lookup entry */
if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
(ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
{
*ifaddr = osif->addr;
*ifindex = osif->ifindex;
return osif->ifp;
}
/* and it must be an OSPF interface */
oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
if (oi)
return oi;
}
/* Unnumbered interface */
else
{
if (osif->ifindex > *ifindex || osif->addr.s_addr)
/* The interface must NOT have valid AF_INET connected address */
/* it must have lager interface index than the lookup entry */
if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
(osif->ifindex > *ifindex))
{
*ifaddr = osif->addr;
*ifindex = osif->ifindex;
return osif->ifp;
}
/* and it must be an OSPF interface */
oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
if (oi)
return oi;
}
}
return NULL;
@ -1560,14 +1615,14 @@ ospf_snmp_iftype (struct interface *ifp)
return ospf_snmp_iftype_broadcast;
}
struct interface *
struct ospf_interface *
ospfIfLookup (struct variable *v, oid *name, size_t *length,
struct in_addr *ifaddr, unsigned int *ifindex, int exact)
{
unsigned int len;
int ifaddr_next = 0;
int ifindex_next = 0;
struct interface *ifp;
struct ospf_interface *oi;
oid *offset;
if (exact)
@ -1599,16 +1654,16 @@ ospfIfLookup (struct variable *v, oid *name, size_t *length,
if (len == 1)
*ifindex = name[v->namelen + IN_ADDR_SIZE];
ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
ifindex_next);
if (ifp)
if (oi)
{
*length = v->namelen + IN_ADDR_SIZE + 1;
offset = name + v->namelen;
oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
offset += IN_ADDR_SIZE;
*offset = *ifindex;
return ifp;
return oi;
}
}
return NULL;
@ -1618,7 +1673,6 @@ static u_char *
ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method)
{
struct interface *ifp;
unsigned int ifindex;
struct in_addr ifaddr;
struct ospf_interface *oi;
@ -1632,11 +1686,7 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
if (ospf == NULL)
return NULL;
ifp = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
if (ifp == NULL)
return NULL;
oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
if (oi == NULL)
return NULL;
@ -1656,7 +1706,7 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
return SNMP_IPADDRESS (ospf_empty_addr);
break;
case OSPFIFTYPE: /* 4 */
return SNMP_INTEGER (ospf_snmp_iftype (ifp));
return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
break;
case OSPFIFADMINSTAT: /* 5 */
if (oi)
@ -1725,14 +1775,14 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
#define OSPF_SNMP_METRIC_VALUE 1
struct interface *
struct ospf_interface *
ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
struct in_addr *ifaddr, unsigned int *ifindex, int exact)
{
unsigned int len;
int ifaddr_next = 0;
int ifindex_next = 0;
struct interface *ifp;
struct ospf_interface *oi;
oid *offset;
int metric;
@ -1769,9 +1819,9 @@ ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
if (len == 1)
*ifindex = name[v->namelen + IN_ADDR_SIZE];
ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
ifindex_next);
if (ifp)
if (oi)
{
*length = v->namelen + IN_ADDR_SIZE + 1 + 1;
offset = name + v->namelen;
@ -1780,7 +1830,7 @@ ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
*offset = *ifindex;
offset++;
*offset = OSPF_SNMP_METRIC_VALUE;
return ifp;
return oi;
}
}
return NULL;
@ -1791,7 +1841,6 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method)
{
/* Currently we support metric 1 only. */
struct interface *ifp;
unsigned int ifindex;
struct in_addr ifaddr;
struct ospf_interface *oi;
@ -1805,11 +1854,7 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
if (ospf == NULL)
return NULL;
ifp = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
if (ifp == NULL)
return NULL;
oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
if (oi == NULL)
return NULL;