ospf6d: add SNMP support for ospfv3*LsdbTable

This includes:
 - ospfv3AsLsdbTable
 - ospfv3AreaLsdbTable
 - ospfv3LinkLsdbTable
This commit is contained in:
Vincent Bernat 2012-06-04 12:59:20 +02:00
parent 3bc4f84efe
commit c349bb8692

View File

@ -90,26 +90,20 @@
#define OSPFv3AREASTUBMETRICTYPE 15 #define OSPFv3AREASTUBMETRICTYPE 15
#define OSPFv3AREATEENABLED 16 #define OSPFv3AREATEENABLED 16
/* OSPFv3 MIB AS Lsdb Table values: ospfv3AsLsdbTable */ /* OSPFv3 MIB * Lsdb Table values: ospfv3*LsdbTable */
#define OSPFv3ASLSDBSEQUENCE 4 #define OSPFv3WWLSDBSEQUENCE 1
#define OSPFv3ASLSDBAGE 5 #define OSPFv3WWLSDBAGE 2
#define OSPFv3ASLSDBCHECKSUM 6 #define OSPFv3WWLSDBCHECKSUM 3
#define OSPFv3ASLSDBADVERTISEMENT 7 #define OSPFv3WWLSDBADVERTISEMENT 4
#define OSPFv3ASLSDBTYPEKNOWN 8 #define OSPFv3WWLSDBTYPEKNOWN 5
/* OSPFv3 MIB Area Lsdb Table values: ospfv3AreaLsdbTable */ /* Three first bits are to identify column */
#define OSPFv3AREALSDBSEQUENCE 5 #define OSPFv3WWCOLUMN 0x7
#define OSPFv3AREALSDBAGE 6 /* Then we use other bits to identify table */
#define OSPFv3AREALSDBCHECKSUM 7 #define OSPFv3WWASTABLE (1 << 3)
#define OSPFv3AREALSDBADVERTISEMENT 8 #define OSPFv3WWAREATABLE (1 << 4)
#define OSPFv3AREALSDBTYPEKNOWN 9 #define OSPFv3WWLINKTABLE (1 << 5)
#define OSPFv3WWVIRTLINKTABLE (1 << 6)
/* OSPFv3 MIB Link Lsdb Table values: ospfv3LinkLsdbTable */
#define OSPFv3LINKLSDBSEQUENCE 6
#define OSPFv3LINKLSDBAGE 7
#define OSPFv3LINKLSDBCHECKSUM 8
#define OSPFv3LINKLSDBADVERTISEMENT 9
#define OSPFv3LINKLSDBTYPEKNOWN 10
/* OSPFv3 MIB Host Table values: ospfv3HostTable */ /* OSPFv3 MIB Host Table values: ospfv3HostTable */
#define OSPFv3HOSTMETRIC 3 #define OSPFv3HOSTMETRIC 3
@ -192,13 +186,6 @@
#define OSPFv3AREAAGGREGATEEFFECT 7 #define OSPFv3AREAAGGREGATEEFFECT 7
#define OSPFv3AREAAGGREGATEROUTETAG 8 #define OSPFv3AREAAGGREGATEROUTETAG 8
/* OSPFv3 MIB Virtual Link Lsdb Table values: ospfv3VirtLinkLsdbTable */
#define OSPFv3VIRTLINKLSDBSEQUENCE 6
#define OSPFv3VIRTLINKLSDBAGE 7
#define OSPFv3VIRTLINKLSDBCHECKSUM 8
#define OSPFv3VIRTLINKLSDBADVERTISEMENT 9
#define OSPFv3VIRTLINKLSDBTYPEKNOWN 10
/* SYNTAX Status from OSPF-MIB. */ /* SYNTAX Status from OSPF-MIB. */
#define OSPF_STATUS_ENABLED 1 #define OSPF_STATUS_ENABLED 1
#define OSPF_STATUS_DISABLED 2 #define OSPF_STATUS_DISABLED 2
@ -223,7 +210,7 @@ static u_char *ospfv3GeneralGroup (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **); int, size_t *, WriteMethod **);
static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *, static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **); int, size_t *, WriteMethod **);
static u_char *ospfv3AreaLsdbEntry (struct variable *, oid *, size_t *, static u_char *ospfv3WwLsdbEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **); int, size_t *, WriteMethod **);
static u_char *ospfv3NbrEntry (struct variable *, oid *, size_t *, static u_char *ospfv3NbrEntry (struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **); int, size_t *, WriteMethod **);
@ -316,18 +303,42 @@ struct variable ospfv3_variables[] =
{OSPFv3AREATEENABLED, INTEGER, RWRITE, ospfv3AreaEntry, {OSPFv3AREATEENABLED, INTEGER, RWRITE, ospfv3AreaEntry,
4, {1, 2, 1, 16}}, 4, {1, 2, 1, 16}},
/* OSPFv3 AS LSDB */
{OSPFv3WWLSDBSEQUENCE | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 3, 1, 4}},
{OSPFv3WWLSDBAGE | OSPFv3WWASTABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry,
4, {1, 3, 1, 5}},
{OSPFv3WWLSDBCHECKSUM | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 3, 1, 6}},
{OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWASTABLE, STRING, RONLY, ospfv3WwLsdbEntry,
4, {1, 3, 1, 7}},
{OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 3, 1, 8}},
/* OSPFv3 Area LSDB */ /* OSPFv3 Area LSDB */
{OSPFv3AREALSDBSEQUENCE, INTEGER, RONLY, ospfv3AreaLsdbEntry, {OSPFv3WWLSDBSEQUENCE | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 4, 1, 5}}, 4, {1, 4, 1, 5}},
{OSPFv3AREALSDBAGE, UNSIGNED, RONLY, ospfv3AreaLsdbEntry, {OSPFv3WWLSDBAGE | OSPFv3WWAREATABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry,
4, {1, 4, 1, 6}}, 4, {1, 4, 1, 6}},
{OSPFv3AREALSDBCHECKSUM, INTEGER, RONLY, ospfv3AreaLsdbEntry, {OSPFv3WWLSDBCHECKSUM | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 4, 1, 7}}, 4, {1, 4, 1, 7}},
{OSPFv3AREALSDBADVERTISEMENT, STRING, RONLY, ospfv3AreaLsdbEntry, {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWAREATABLE, STRING, RONLY, ospfv3WwLsdbEntry,
4, {1, 4, 1, 8}}, 4, {1, 4, 1, 8}},
{OSPFv3AREALSDBTYPEKNOWN, INTEGER, RONLY, ospfv3AreaLsdbEntry, {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 4, 1, 9}}, 4, {1, 4, 1, 9}},
/* OSPFv3 Link LSDB */
{OSPFv3WWLSDBSEQUENCE | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 5, 1, 6}},
{OSPFv3WWLSDBAGE | OSPFv3WWLINKTABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry,
4, {1, 5, 1, 7}},
{OSPFv3WWLSDBCHECKSUM | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 5, 1, 8}},
{OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWLINKTABLE, STRING, RONLY, ospfv3WwLsdbEntry,
4, {1, 5, 1, 9}},
{OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry,
4, {1, 5, 1, 10}},
/* OSPFv3 interfaces */ /* OSPFv3 interfaces */
{OSPFv3IFAREAID, UNSIGNED, RONLY, ospfv3IfEntry, {OSPFv3IFAREAID, UNSIGNED, RONLY, ospfv3IfEntry,
4, {1, 7, 1, 3}}, 4, {1, 7, 1, 3}},
@ -596,12 +607,18 @@ ospfv3AreaEntry (struct variable *v, oid *name, size_t *length,
return NULL; return NULL;
} }
static int
if_icmp_func (struct interface *ifp1, struct interface *ifp2)
{
return (ifp1->ifindex - ifp2->ifindex);
}
static u_char * static u_char *
ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length, ospfv3WwLsdbEntry (struct variable *v, oid *name, size_t *length,
int exact, size_t *var_len, WriteMethod **write_method) int exact, size_t *var_len, WriteMethod **write_method)
{ {
struct ospf6_lsa *lsa = NULL; struct ospf6_lsa *lsa = NULL;
u_int32_t area_id, id, adv_router; u_int32_t ifindex, area_id, id, instid, adv_router;
u_int16_t type; u_int16_t type;
int len; int len;
oid *offset; oid *offset;
@ -609,12 +626,15 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
char a[16], b[16], c[16]; char a[16], b[16], c[16];
struct ospf6_area *oa; struct ospf6_area *oa;
struct listnode *node; struct listnode *node;
struct interface *iif;
struct ospf6_interface *oi = NULL;
struct list *ifslist;
if (smux_header_table(v, name, length, exact, var_len, write_method) if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED) == MATCH_FAILED)
return NULL; return NULL;
area_id = type = id = adv_router = 0; instid = ifindex = area_id = type = id = adv_router = 0;
/* Check OSPFv3 instance. */ /* Check OSPFv3 instance. */
if (ospf6 == NULL) if (ospf6 == NULL)
@ -624,17 +644,38 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
offset = name + v->namelen; offset = name + v->namelen;
offsetlen = *length - v->namelen; offsetlen = *length - v->namelen;
#define OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET 4 if (exact && (v->magic & OSPFv3WWASTABLE) && offsetlen != 3)
return NULL;
if (exact && offsetlen != OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET) if (exact && (v->magic & OSPFv3WWAREATABLE) && offsetlen != 4)
return NULL;
if (exact && (v->magic & OSPFv3WWLINKTABLE) && offsetlen != 5)
return NULL; return NULL;
if (v->magic & OSPFv3WWLINKTABLE)
{
/* Parse ifindex */
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;
}
else if (v->magic & OSPFv3WWAREATABLE)
{
/* Parse area-id */ /* Parse area-id */
len = (offsetlen < 1 ? 0 : 1); len = (offsetlen < 1 ? 0 : 1);
if (len) if (len)
area_id = htonl (*offset); area_id = htonl (*offset);
offset += len; offset += len;
offsetlen -= len; offsetlen -= len;
}
/* Parse type */ /* Parse type */
len = (offsetlen < 1 ? 0 : 1); len = (offsetlen < 1 ? 0 : 1);
@ -657,52 +698,102 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
offset += len; offset += len;
offsetlen -= len; offsetlen -= len;
inet_ntop (AF_INET, &area_id, a, sizeof (a));
inet_ntop (AF_INET, &adv_router, b, sizeof (b));
inet_ntop (AF_INET, &id, c, sizeof (c));
zlog_debug ("SNMP access by lsdb: area=%s exact=%d length=%lu magic=%d"
" type=%#x adv_router=%s id=%s",
a, exact, (u_long)*length, v->magic, ntohs (type), b, c);
if (exact) if (exact)
{
if (v->magic & OSPFv3WWASTABLE)
{
lsa = ospf6_lsdb_lookup (type, id, adv_router, ospf6->lsdb);
}
else if (v->magic & OSPFv3WWAREATABLE)
{ {
oa = ospf6_area_lookup (area_id, ospf6); oa = ospf6_area_lookup (area_id, ospf6);
lsa = ospf6_lsdb_lookup (type, id, adv_router, oa->lsdb); lsa = ospf6_lsdb_lookup (type, id, adv_router, oa->lsdb);
} }
else if (v->magic & OSPFv3WWLINKTABLE)
{
oi = ospf6_interface_lookup_by_ifindex (ifindex);
if (oi->instance_id != instid) return NULL;
lsa = ospf6_lsdb_lookup (type, id, adv_router, oi->lsdb);
}
}
else else
{ {
if (v->magic & OSPFv3WWASTABLE)
{
if (ospf6->lsdb->count)
lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
ospf6->lsdb);
}
else if (v->magic & OSPFv3WWAREATABLE)
for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
{ {
if (lsa)
continue;
if (oa->area_id < area_id) if (oa->area_id < area_id)
continue; continue;
if (oa->lsdb->count)
lsa = ospf6_lsdb_lookup_next (type, id, adv_router, lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
oa->lsdb); oa->lsdb);
if (! lsa) if (lsa) break;
{
type = 0; type = 0;
id = 0; id = 0;
adv_router = 0; adv_router = 0;
} }
else if (v->magic & OSPFv3WWLINKTABLE)
{
/* 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, node, iif))
listnode_add_sort (ifslist, iif);
for (ALL_LIST_ELEMENTS_RO (ifslist, node, iif))
{
if (!iif->ifindex) continue;
oi = ospf6_interface_lookup_by_ifindex (iif->ifindex);
if (!oi) continue;
if (iif->ifindex < ifindex) continue;
if (oi->instance_id < instid) continue;
if (oi->lsdb->count)
lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
oi->lsdb);
if (lsa) break;
type = 0;
id = 0;
adv_router = 0;
oi = NULL;
}
list_delete_all_node (ifslist);
} }
} }
if (! lsa) if (! lsa)
{
zlog_debug ("SNMP respond: No LSA to return");
return NULL; return NULL;
/* Add indexes */
if (v->magic & OSPFv3WWASTABLE)
{
*length = v->namelen + 3;
offset = name + v->namelen;
} }
oa = OSPF6_AREA (lsa->lsdb->data); else if (v->magic & OSPFv3WWAREATABLE)
{
zlog_debug ("SNMP respond: area: %s lsa: %s", oa->name, lsa->name); *length = v->namelen + 4;
/* Add Index (AreaId, Type, RouterId, Lsid) */
*length = v->namelen + OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET;
offset = name + v->namelen; offset = name + v->namelen;
*offset = ntohl (oa->area_id); *offset = ntohl (oa->area_id);
offset++; offset++;
}
else if (v->magic & OSPFv3WWLINKTABLE)
{
*length = v->namelen + 5;
offset = name + v->namelen;
*offset = oi->interface->ifindex;
offset++;
*offset = oi->instance_id;
offset++;
}
*offset = ntohs (lsa->header->type); *offset = ntohs (lsa->header->type);
offset++; offset++;
*offset = ntohl (lsa->header->adv_router); *offset = ntohl (lsa->header->adv_router);
@ -711,23 +802,23 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
offset++; offset++;
/* Return the current value of the variable */ /* Return the current value of the variable */
switch (v->magic) switch (v->magic & OSPFv3WWCOLUMN)
{ {
case OSPFv3AREALSDBSEQUENCE: case OSPFv3WWLSDBSEQUENCE:
return SNMP_INTEGER (ntohl (lsa->header->seqnum)); return SNMP_INTEGER (ntohl (lsa->header->seqnum));
break; break;
case OSPFv3AREALSDBAGE: case OSPFv3WWLSDBAGE:
ospf6_lsa_age_current (lsa); ospf6_lsa_age_current (lsa);
return SNMP_INTEGER (ntohs (lsa->header->age)); return SNMP_INTEGER (ntohs (lsa->header->age));
break; break;
case OSPFv3AREALSDBCHECKSUM: case OSPFv3WWLSDBCHECKSUM:
return SNMP_INTEGER (ntohs (lsa->header->checksum)); return SNMP_INTEGER (ntohs (lsa->header->checksum));
break; break;
case OSPFv3AREALSDBADVERTISEMENT: case OSPFv3WWLSDBADVERTISEMENT:
*var_len = ntohs (lsa->header->length); *var_len = ntohs (lsa->header->length);
return (u_char *) lsa->header; return (u_char *) lsa->header;
break; break;
case OSPFv3AREALSDBTYPEKNOWN: case OSPFv3WWLSDBTYPEKNOWN:
return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ? return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ?
SNMP_TRUE : SNMP_FALSE); SNMP_TRUE : SNMP_FALSE);
break; break;
@ -735,12 +826,6 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
return NULL; return NULL;
} }
static int
if_icmp_func (struct interface *ifp1, struct interface *ifp2)
{
return (ifp1->ifindex - ifp2->ifindex);
}
static u_char * static u_char *
ospfv3IfEntry (struct variable *v, oid *name, size_t *length, ospfv3IfEntry (struct variable *v, oid *name, size_t *length,
int exact, size_t *var_len, WriteMethod **write_method) int exact, size_t *var_len, WriteMethod **write_method)