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> 2005-10-01 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* ospf_dump.c: Remove local hard-coded table ospf_redistributed_proto. * 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) if (addr)
{ {
/* Usual interfaces --> Sort them based on interface IPv4 addresses */
if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr)) if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
break; break;
} }
else else
{ {
/* Unnumbered interface. */ /* Unnumbered interfaces --> Sort them based on interface indexes */
if (osif->addr.s_addr != 0 || osif->ifindex > ifindex) if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
break; break;
} }
@ -1471,76 +1472,130 @@ ospf_snmp_if_update (struct interface *ifp)
} }
osif = ospf_snmp_if_new (); osif = ospf_snmp_if_new ();
if (addr) if (addr) /* Usual interface */
{
osif->addr = *addr; 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->ifindex = ifindex;
osif->ifp = ifp; osif->ifp = ifp;
listnode_add_after (ospf_snmp_iflist, pn, osif); 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) ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
{ {
struct listnode *node; struct listnode *node;
struct ospf_snmp_if *osif; 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)) for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
{ {
if (ifaddr->s_addr) if (ifaddr->s_addr)
{ {
if (IPV4_ADDR_SAME (&osif->addr, ifaddr)) if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
return osif->ifp; oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
} }
else else
{ {
if (osif->ifindex == *ifindex) 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, ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
int ifaddr_next, int ifindex_next) int ifaddr_next, int ifindex_next)
{ {
struct ospf_snmp_if *osif; struct ospf_snmp_if *osif;
struct listnode *nn; 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) if (ifaddr_next)
{ {
nn = listhead (ospf_snmp_iflist); for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
if (nn)
{ {
osif = listgetdata (nn); osif = listgetdata (nn);
*ifaddr = osif->addr; *ifaddr = osif->addr;
*ifindex = osif->ifindex; *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; return NULL;
} }
/* An instance is specified --> Return the next OSPF interface */
for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif)) for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
{ {
/* Usual interface */
if (ifaddr->s_addr) if (ifaddr->s_addr)
{ /* The interface must have valid AF_INET connected address */
if (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)) /* 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; *ifaddr = osif->addr;
*ifindex = osif->ifindex; *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 else
{ /* The interface must NOT have valid AF_INET connected address */
if (osif->ifindex > *ifindex || osif->addr.s_addr) /* 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; *ifaddr = osif->addr;
*ifindex = osif->ifindex; *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; return NULL;
@ -1560,14 +1615,14 @@ ospf_snmp_iftype (struct interface *ifp)
return ospf_snmp_iftype_broadcast; return ospf_snmp_iftype_broadcast;
} }
struct interface * struct ospf_interface *
ospfIfLookup (struct variable *v, oid *name, size_t *length, ospfIfLookup (struct variable *v, oid *name, size_t *length,
struct in_addr *ifaddr, unsigned int *ifindex, int exact) struct in_addr *ifaddr, unsigned int *ifindex, int exact)
{ {
unsigned int len; unsigned int len;
int ifaddr_next = 0; int ifaddr_next = 0;
int ifindex_next = 0; int ifindex_next = 0;
struct interface *ifp; struct ospf_interface *oi;
oid *offset; oid *offset;
if (exact) if (exact)
@ -1599,16 +1654,16 @@ ospfIfLookup (struct variable *v, oid *name, size_t *length,
if (len == 1) if (len == 1)
*ifindex = name[v->namelen + IN_ADDR_SIZE]; *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); ifindex_next);
if (ifp) if (oi)
{ {
*length = v->namelen + IN_ADDR_SIZE + 1; *length = v->namelen + IN_ADDR_SIZE + 1;
offset = name + v->namelen; offset = name + v->namelen;
oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE); oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
offset += IN_ADDR_SIZE; offset += IN_ADDR_SIZE;
*offset = *ifindex; *offset = *ifindex;
return ifp; return oi;
} }
} }
return NULL; return NULL;
@ -1618,7 +1673,6 @@ static u_char *
ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact, ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) size_t *var_len, WriteMethod **write_method)
{ {
struct interface *ifp;
unsigned int ifindex; unsigned int ifindex;
struct in_addr ifaddr; struct in_addr ifaddr;
struct ospf_interface *oi; struct ospf_interface *oi;
@ -1632,11 +1686,7 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
if (ospf == NULL) if (ospf == NULL)
return NULL; return NULL;
ifp = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact); oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
if (ifp == NULL)
return NULL;
oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
if (oi == NULL) if (oi == NULL)
return NULL; return NULL;
@ -1656,7 +1706,7 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
return SNMP_IPADDRESS (ospf_empty_addr); return SNMP_IPADDRESS (ospf_empty_addr);
break; break;
case OSPFIFTYPE: /* 4 */ case OSPFIFTYPE: /* 4 */
return SNMP_INTEGER (ospf_snmp_iftype (ifp)); return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
break; break;
case OSPFIFADMINSTAT: /* 5 */ case OSPFIFADMINSTAT: /* 5 */
if (oi) if (oi)
@ -1725,14 +1775,14 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
#define OSPF_SNMP_METRIC_VALUE 1 #define OSPF_SNMP_METRIC_VALUE 1
struct interface * struct ospf_interface *
ospfIfMetricLookup (struct variable *v, oid *name, size_t *length, ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
struct in_addr *ifaddr, unsigned int *ifindex, int exact) struct in_addr *ifaddr, unsigned int *ifindex, int exact)
{ {
unsigned int len; unsigned int len;
int ifaddr_next = 0; int ifaddr_next = 0;
int ifindex_next = 0; int ifindex_next = 0;
struct interface *ifp; struct ospf_interface *oi;
oid *offset; oid *offset;
int metric; int metric;
@ -1769,9 +1819,9 @@ ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
if (len == 1) if (len == 1)
*ifindex = name[v->namelen + IN_ADDR_SIZE]; *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); ifindex_next);
if (ifp) if (oi)
{ {
*length = v->namelen + IN_ADDR_SIZE + 1 + 1; *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
offset = name + v->namelen; offset = name + v->namelen;
@ -1780,7 +1830,7 @@ ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
*offset = *ifindex; *offset = *ifindex;
offset++; offset++;
*offset = OSPF_SNMP_METRIC_VALUE; *offset = OSPF_SNMP_METRIC_VALUE;
return ifp; return oi;
} }
} }
return NULL; return NULL;
@ -1791,7 +1841,6 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
size_t *var_len, WriteMethod **write_method) size_t *var_len, WriteMethod **write_method)
{ {
/* Currently we support metric 1 only. */ /* Currently we support metric 1 only. */
struct interface *ifp;
unsigned int ifindex; unsigned int ifindex;
struct in_addr ifaddr; struct in_addr ifaddr;
struct ospf_interface *oi; struct ospf_interface *oi;
@ -1805,11 +1854,7 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
if (ospf == NULL) if (ospf == NULL)
return NULL; return NULL;
ifp = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact); oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
if (ifp == NULL)
return NULL;
oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
if (oi == NULL) if (oi == NULL)
return NULL; return NULL;