frr/ldpd/ldp_snmp.c

1225 lines
34 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LDP SNMP support
* Copyright (C) 2020 Volta Networks, Inc.
*/
/*
* This is minimal read-only implementations providing
* mplsLdpModuleReadOnlyCompliance as described in RFC 3815.
*/
#include <zebra.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "vrf.h"
#include "if.h"
#include "log.h"
#include "prefix.h"
#include "table.h"
#include "command.h"
#include "memory.h"
#include "smux.h"
#include "libfrr.h"
#include "lib/version.h"
#include "ldpd.h"
#include "ldpe.h"
/* SNMP value hack. */
#define COUNTER32 ASN_COUNTER
#define INTEGER ASN_INTEGER
#define UNSIGNED32 ASN_GAUGE
#define TIMESTAMP ASN_TIMETICKS
#define TIMETICKS ASN_TIMETICKS
#define STRING ASN_OCTET_STR
#define IPADDRESS ASN_IPADDRESS
#define LDP_LSRID_IDX_LEN 6
#define LDP_ENTITY_IDX_LEN 1
#define LDP_ADJACENCY_IDX_LEN 1
/* MPLS-LDP-STD-MIB. */
#define MPLS_LDP_STD_MIB 1, 3, 6, 1, 2, 1, 10, 166, 4
#define MPLS_LDP_LSR_ID 0
#define MPLS_LDP_LSR_LOOP_DETECTION_CAPABLE 0
#define MPLS_LDP_ENTITY_LAST_CHANGE 0
#define MPLS_LDP_ENTITY_INDEX_NEXT 0
/* Declare static local variables for convenience. */
SNMP_LOCAL_VARIABLES
/* LDP-MIB instances. */
static oid ldp_oid[] = {MPLS_LDP_STD_MIB};
static oid ldp_trap_oid[] = {MPLS_LDP_STD_MIB, 0};
static uint8_t snmp_ldp_rtrid[6] = {0, 0, 0, 0, 0};
#define LDP_DEFAULT_ENTITY_INDEX 1
#define MPLSLDPLSRLOOPDETECTIONCAPABLE_NONE 1
#define MPLSLDPLSRLOOPDETECTIONCAPABLE_OTHER 2
#define MPLSLDPLSRLOOPDETECTIONCAPABLE_HOPCOUNT 3
#define MPLSLDPLSRLOOPDETECTIONCAPABLE_PATHVECTOR 4
#define MPLSLDPLSRLOOPDETECTIONCAPABLE_HOPCOUNTANDPATHVECTOR 5
/* MPLS LDP mplsLdpHelloAdjacencyTable. */
#define MPLSLDPHELLOADJACENCYINDEX 1
#define MPLSLDPHELLOADJACENCYHOLDTIMEREM 2
#define MPLSLDPHELLOADJACENCYHOLDTIME 3
#define MPLSLDPHELLOADJACENCYTYPE 4
/* enums for column mplsLdpHelloAdjacencyType */
#define MPLSLDPHELLOADJACENCYTYPE_LINK 1
#define MPLSLDPHELLOADJACENCYTYPE_TARGETED 2
#define MPLSLDPPEERTRANSPORTADDRTYPE_UNKNOWN 0
#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV4 1
#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV6 2
#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV4Z 3
#define MPLSLDPPEERTRANSPORTADDRTYPE_IPV6Z 4
#define MPLSLDPPEERTRANSPORTADDRTYPE_DNS 16
#define DOWNSTREAMONDEMAND 1
#define DOWNSTREAMUNSOLICITED 2
#define CONSERVATIVERETENTION 1
#define LIBERALRETENTION 2
#define TRANSPORTADDRINTERFACE 1
#define TRANSPORTADDRLOOPBACK 2
#define LABELTYPEGENERIC 1
#define STORAGETYPENONVOLATILE 3
#define ROWSTATUSACTIVE 4
#define ADMINSTATUSENABLED 1
#define OPERSTATUSENABLED 2
/* MPLS LDP mplsLdpPeerTable */
#define MPLSLDPPEERLDPID 1
#define MPLSLDPPEERLABELDISTMETHOD 2
#define MPLSLDPPEERPATHVECTORLIMIT 3
#define MPLSLDPPEERTRANSPORTADDRTYPE 4
#define MPLSLDPPEERTRANSPORTADDR 5
#define MPLSLDPSESSIONROLE_UNKNOWN 1
#define MPLSLDPSESSIONROLE_ACTIVE 2
#define MPLSLDPSESSIONROLE_PASSIVE 3
#define MPLSLDPSESSIONSTATE_NONEXISTENT 1
#define MPLSLDPSESSIONSTATE_INITIALIZED 2
#define MPLSLDPSESSIONSTATE_OPENREC 3
#define MPLSLDPSESSIONSTATE_OPENSENT 4
#define MPLSLDPSESSIONSTATE_OPERATIONAL 5
/* MPLS LDP mplsLdpSessionTable */
#define MPLSLDPSESSIONSTATELASTCHANGE 1
#define MPLSLDPSESSIONSTATE 2
#define MPLSLDPSESSIONROLE 3
#define MPLSLDPSESSIONPROTOCOLVERSION 4
#define MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM 5
#define MPLSLDPSESSIONKEEPALIVETIME 6
#define MPLSLDPSESSIONMAXPDULENGTH 7
#define MPLSLDPSESSIONDISCONTINUITYTIME 8
/* MPLS LDP mplsLdpEntityTable */
#define MPLSLDPENTITYLDPID 1
#define MPLSLDPENTITYINDEX 2
#define MPLSLDPENTITYPROTOCOLVERSION 3
#define MPLSLDPENTITYADMINSTATUS 4
#define MPLSLDPENTITYOPERSTATUS 5
#define MPLSLDPENTITYTCPPORT 6
#define MPLSLDPENTITYUDPDSCPORT 7
#define MPLSLDPENTITYMAXPDULENGTH 8
#define MPLSLDPENTITYKEEPALIVEHOLDTIMER 9
#define MPLSLDPENTITYHELLOHOLDTIMER 10
#define MPLSLDPENTITYINITSESSIONTHRESHOLD 11
#define MPLSLDPENTITYLABELDISTMETHOD 12
#define MPLSLDPENTITYLABELRETENTIONMODE 13
#define MPLSLDPENTITYPATHVECTORLIMIT 14
#define MPLSLDPENTITYHOPCOUNTLIMIT 15
#define MPLSLDPENTITYTRANSPORTADDRKIND 16
#define MPLSLDPENTITYTARGETPEER 17
#define MPLSLDPENTITYTARGETPEERADDRTYPE 18
#define MPLSLDPENTITYTARGETPEERADDR 19
#define MPLSLDPENTITYLABELTYPE 20
#define MPLSLDPENTITYDISCONTINUITYTIME 21
#define MPLSLDPENTITYSTORAGETYPE 22
#define MPLSLDPENTITYROWSTATUS 23
/* MPLS LDP mplsLdpEntityStatsTable */
#define MPLSLDPENTITYSTATSSESSIONATTEMPTS 1
#define MPLSLDPENTITYSTATSSESSIONREJHELLO 2
#define MPLSLDPENTITYSTATSSESSIONREJAD 3
#define MPLSLDPENTITYSTATSSESSIONREJMAXPDU 4
#define MPLSLDPENTITYSTATSSESSIONREJLR 5
#define MPLSLDPENTITYSTATSBADLDPID 6
#define MPLSLDPENTITYSTATSBADPDULENGTH 7
#define MPLSLDPENTITYSTATSBADMSGLENGTH 8
#define MPLSLDPENTITYSTATSBADTLVLENGTH 9
#define MPLSLDPENTITYSTATSMALFORMEDTLV 10
#define MPLSLDPENTITYSTATSKEEPALIVEEXP 11
#define MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY 12
#define MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY 13
#define MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS 1
#define MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS 2
static uint8_t *ldpLsrId(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
*var_len = 4;
return (uint8_t *)&leconf->rtr_id.s_addr;
}
static uint8_t *ldpLoopDetectCap(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
return SNMP_INTEGER(MPLSLDPLSRLOOPDETECTIONCAPABLE_NONE);
}
extern uint32_t ldp_start_time;
static uint8_t *ldpEntityLastChange(struct variable *v, oid name[],
size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
*var_len = sizeof(time_t);
return (uint8_t *) &(leconf->config_change_time);
}
static uint8_t *ldpEntityIndexNext(struct variable *v, oid name[],
size_t *length,int exact, size_t *var_len,
WriteMethod **write_method)
{
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
return SNMP_INTEGER(0);
}
#define LDP_ENTITY_TOTAL_LEN 21
#define LDP_ENTITY_MAX_IDX_LEN 6
static struct ldpd_af_conf *ldpEntityTable_lookup(struct variable *v, oid *name,
size_t *length, int exact,
uint32_t *index)
{
int len;
struct ldpd_af_conf *af_v4, *af_v6;
af_v4 = &leconf->ipv4;
af_v6 = &leconf->ipv6;
if (exact) {
if (*length != LDP_ENTITY_TOTAL_LEN)
return NULL;
if (leconf->trans_pref == DUAL_STACK_LDPOV6 &&
af_v6->flags & F_LDPD_AF_ENABLED) {
*index = 2;
return af_v6;
} else {
*index = 1;
return af_v4;
}
} else {
/* only support one router id so can just skip */
len = *length - v->namelen - LDP_ENTITY_MAX_IDX_LEN;
if (len <= 0) {
if (leconf->trans_pref == DUAL_STACK_LDPOV6 &&
af_v6->flags & F_LDPD_AF_ENABLED) {
*index = 2;
return af_v6;
} else {
*index = 1;
return af_v4;
}
}
}
return NULL;
}
static uint8_t *ldpEntityTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct ldpd_af_conf *af;
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t index = 0;
*write_method = NULL;
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
af = ldpEntityTable_lookup(v, name, length, exact, &index);
if (af == NULL)
return NULL;
if (!exact) {
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
*length = LDP_ENTITY_TOTAL_LEN;
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
}
/* Return the current value of the variable */
switch (v->magic) {
case MPLSLDPENTITYLDPID:
*var_len = 6;
memcpy (snmp_ldp_rtrid, &entityLdpId, IN_ADDR_SIZE);
return (uint8_t *)snmp_ldp_rtrid;
case MPLSLDPENTITYINDEX:
return SNMP_INTEGER(LDP_DEFAULT_ENTITY_INDEX);
case MPLSLDPENTITYPROTOCOLVERSION:
return SNMP_INTEGER(LDP_VERSION);
case MPLSLDPENTITYADMINSTATUS:
return SNMP_INTEGER(ADMINSTATUSENABLED);
case MPLSLDPENTITYOPERSTATUS:
return SNMP_INTEGER(OPERSTATUSENABLED);
case MPLSLDPENTITYTCPPORT:
return SNMP_INTEGER(LDP_PORT);
case MPLSLDPENTITYUDPDSCPORT:
return SNMP_INTEGER(LDP_PORT);
case MPLSLDPENTITYMAXPDULENGTH:
return SNMP_INTEGER(LDP_MAX_LEN);
case MPLSLDPENTITYKEEPALIVEHOLDTIMER:
return SNMP_INTEGER(af->keepalive);
case MPLSLDPENTITYHELLOHOLDTIMER:
return SNMP_INTEGER(af->lhello_holdtime);
case MPLSLDPENTITYINITSESSIONTHRESHOLD:
return SNMP_INTEGER(0); /* not supported */
case MPLSLDPENTITYLABELDISTMETHOD:
return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
case MPLSLDPENTITYLABELRETENTIONMODE:
return SNMP_INTEGER(LIBERALRETENTION);
case MPLSLDPENTITYPATHVECTORLIMIT:
return SNMP_INTEGER(0); /* not supported */
case MPLSLDPENTITYHOPCOUNTLIMIT:
return SNMP_INTEGER(0);
case MPLSLDPENTITYTRANSPORTADDRKIND:
return SNMP_INTEGER(TRANSPORTADDRLOOPBACK);
case MPLSLDPENTITYTARGETPEER:
return SNMP_INTEGER(1);
case MPLSLDPENTITYTARGETPEERADDRTYPE:
if (index == 1)
return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
else
return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
case MPLSLDPENTITYTARGETPEERADDR:
if (index == 1) {
*var_len = sizeof(af->trans_addr.v4);
return ((uint8_t *)&af->trans_addr.v4);
}else {
*var_len = sizeof(af->trans_addr.v6);
return ((uint8_t *)&af->trans_addr.v6);
}
case MPLSLDPENTITYLABELTYPE:
return SNMP_INTEGER(LABELTYPEGENERIC);
case MPLSLDPENTITYDISCONTINUITYTIME:
return SNMP_INTEGER(0);
case MPLSLDPENTITYSTORAGETYPE:
return SNMP_INTEGER(STORAGETYPENONVOLATILE);
case MPLSLDPENTITYROWSTATUS:
return SNMP_INTEGER(ROWSTATUSACTIVE);
default:
return NULL;
}
return NULL;
}
static uint8_t *ldpEntityStatsTable(struct variable *v, oid name[],
size_t *length, int exact, size_t *var_len,
WriteMethod **write_method)
{
struct in_addr entityLdpId = {.s_addr = 0};
int len;
*write_method = NULL;
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
if (exact) {
if (*length != LDP_ENTITY_TOTAL_LEN)
return NULL;
} else {
len = *length - v->namelen - LDP_ENTITY_MAX_IDX_LEN;
if (len > 0)
return NULL;
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
*length = LDP_ENTITY_TOTAL_LEN;
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
}
/* Return the current value of the variable */
switch (v->magic) {
case MPLSLDPENTITYSTATSSESSIONATTEMPTS:
return SNMP_INTEGER(leconf->stats.session_attempts);
case MPLSLDPENTITYSTATSSESSIONREJHELLO:
return SNMP_INTEGER(leconf->stats.session_rejects_hello);
case MPLSLDPENTITYSTATSSESSIONREJAD:
return SNMP_INTEGER(leconf->stats.session_rejects_ad);
case MPLSLDPENTITYSTATSSESSIONREJMAXPDU:
return SNMP_INTEGER(leconf->stats.session_rejects_max_pdu);
case MPLSLDPENTITYSTATSSESSIONREJLR:
return SNMP_INTEGER(leconf->stats.session_rejects_lr);
case MPLSLDPENTITYSTATSBADLDPID:
return SNMP_INTEGER(leconf->stats.bad_ldp_id);
case MPLSLDPENTITYSTATSBADPDULENGTH:
return SNMP_INTEGER(leconf->stats.bad_pdu_len);
case MPLSLDPENTITYSTATSBADMSGLENGTH:
return SNMP_INTEGER(leconf->stats.bad_msg_len);
case MPLSLDPENTITYSTATSBADTLVLENGTH:
return SNMP_INTEGER(leconf->stats.bad_tlv_len);
case MPLSLDPENTITYSTATSMALFORMEDTLV:
return SNMP_INTEGER(leconf->stats.malformed_tlv);
case MPLSLDPENTITYSTATSKEEPALIVEEXP:
return SNMP_INTEGER(leconf->stats.keepalive_timer_exp);
case MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY:
return SNMP_INTEGER(leconf->stats.shutdown_rcv_notify);
case MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY:
return SNMP_INTEGER(leconf->stats.shutdown_send_notify);
default:
return NULL;
}
return NULL;
}
#define LDP_ADJACENCY_ENTRY_MAX_IDX_LEN 14
static void ldpHelloAdjacencyTable_oid_to_index(
struct variable *v, oid name[],
size_t *length,
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId,
uint32_t *adjacencyIndex)
{
oid *offset = name + v->namelen;
int offsetlen = *length - v->namelen;
int len = offsetlen;
if (len > LDP_ADJACENCY_ENTRY_MAX_IDX_LEN)
len = LDP_ADJACENCY_ENTRY_MAX_IDX_LEN;
if (len >= LDP_LSRID_IDX_LEN)
oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
offset += LDP_LSRID_IDX_LEN;
offsetlen -= LDP_LSRID_IDX_LEN;
len = offsetlen;
if (len > LDP_ENTITY_IDX_LEN)
len = LDP_ENTITY_IDX_LEN;
if (len >= LDP_ENTITY_IDX_LEN)
*entityIndex = offset[0];
offset += LDP_ENTITY_IDX_LEN;
offsetlen -= LDP_ENTITY_IDX_LEN;
len = offsetlen;
if (len > LDP_LSRID_IDX_LEN)
len = LDP_LSRID_IDX_LEN;
if (len >= LDP_LSRID_IDX_LEN)
oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
offset += LDP_LSRID_IDX_LEN;
offsetlen -= LDP_LSRID_IDX_LEN;
len = offsetlen;
if (len > LDP_ADJACENCY_IDX_LEN)
len = LDP_ADJACENCY_IDX_LEN;
if (len >= LDP_ADJACENCY_IDX_LEN)
*adjacencyIndex = offset[0];
}
static struct adj *
nbr_get_adj_by_index(struct nbr *nbr, uint32_t adjacencyIndex)
{
struct adj *adj;
uint32_t i = 0;
RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
if (++i == adjacencyIndex)
return adj;
return NULL;
}
static struct ctl_adj *
ldpHelloAdjacencyTable_lookup_helper(
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId,
uint32_t *adjacencyIndex)
{
struct ctl_adj *ctl_adj = NULL;
struct adj *adj = NULL;
struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
if (cur_nbr)
/* If found nbr, then look to see if the
* adjacency exists
*/
adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex);
if (adj)
ctl_adj = adj_to_ctl(adj);
return ctl_adj;
}
static struct ctl_adj *
ldpHelloAdjacencyTable_next_helper(
int first,
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId,
uint32_t *adjacencyIndex)
{
struct ctl_adj *ctl_adj = NULL;
struct nbr *nbr = NULL;
struct adj *adj = NULL;
if (first)
nbr = nbr_get_first_ldpid();
else {
struct nbr *cur_nbr = nbr_find_ldpid(peerLdpId->s_addr);
if (cur_nbr)
/* If found nbr, then look to see if the
* adjacency exists
*/
adj = nbr_get_adj_by_index(cur_nbr, *adjacencyIndex + 1);
if (adj)
*adjacencyIndex += 1;
else
nbr = nbr_get_next_ldpid(peerLdpId->s_addr);
}
if (!adj && nbr) {
adj = RB_MIN(nbr_adj_head, &nbr->adj_tree);
*adjacencyIndex = 1;
}
if (adj)
ctl_adj = adj_to_ctl(adj);
return ctl_adj;
}
#define HELLO_ADJ_MAX_IDX_LEN 14
static struct ctl_adj *
ldpHelloAdjacencyTable_lookup(struct variable *v, oid name[],
size_t *length, int exact,
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId,
uint32_t *adjacencyIndex)
{
struct ctl_adj *hello_adj = NULL;
if (exact) {
if (*length < HELLO_ADJ_MAX_IDX_LEN)
return NULL;
ldpHelloAdjacencyTable_oid_to_index(
v, name, length,
entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
hello_adj = ldpHelloAdjacencyTable_lookup_helper(
entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
} else {
int first = 0;
int offsetlen = *length - v->namelen;
if (offsetlen < HELLO_ADJ_MAX_IDX_LEN)
first = 1;
ldpHelloAdjacencyTable_oid_to_index(
v, name, length,
entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
hello_adj = ldpHelloAdjacencyTable_next_helper(first,
entityLdpId, entityIndex, peerLdpId, adjacencyIndex);
}
return hello_adj;
}
static uint8_t *ldpHelloAdjacencyTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t entityIndex = 0;
struct in_addr peerLdpId = {.s_addr = 0};
uint32_t adjacencyIndex = 0;
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
struct ctl_adj *ctl_adj = ldpHelloAdjacencyTable_lookup(v, name,
length, exact,
&entityLdpId, &entityIndex, &peerLdpId, &adjacencyIndex);
if (!ctl_adj)
return NULL;
if (!exact) {
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
struct in_addr entityLdpId = {.s_addr = 0};
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
struct in_addr peerLdpId = ctl_adj->id;
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = LDP_DEFAULT_ENTITY_INDEX;
oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
name[v->namelen + 11] = 0;
name[v->namelen + 12] = 0;
name[v->namelen + 13] = adjacencyIndex;
/* Set length */
*length = v->namelen + HELLO_ADJ_MAX_IDX_LEN;
}
switch (v->magic) {
case MPLSLDPHELLOADJACENCYINDEX:
return SNMP_INTEGER(adjacencyIndex);
case MPLSLDPHELLOADJACENCYHOLDTIMEREM:
return SNMP_INTEGER(ctl_adj->holdtime_remaining);
case MPLSLDPHELLOADJACENCYHOLDTIME:
return SNMP_INTEGER(ctl_adj->holdtime);
case MPLSLDPHELLOADJACENCYTYPE:
if (ctl_adj->type == HELLO_LINK)
return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_LINK);
return SNMP_INTEGER(MPLSLDPHELLOADJACENCYTYPE_TARGETED);
default:
return NULL;
}
return NULL;
}
#define LDP_LSRID_IDX_LEN 6
#define LDP_ENTITY_IDX_LEN 1
#define LDP_PEER_ENTRY_MAX_IDX_LEN 13
static void ldpPeerTable_oid_to_index(
struct variable *v, oid name[],
size_t *length,
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId)
{
oid *offset = name + v->namelen;
int offsetlen = *length - v->namelen;
int len = offsetlen;
if (len > LDP_PEER_ENTRY_MAX_IDX_LEN)
len = LDP_PEER_ENTRY_MAX_IDX_LEN;
if (len >= LDP_LSRID_IDX_LEN)
oid2in_addr(offset, sizeof(struct in_addr), entityLdpId);
offset += LDP_LSRID_IDX_LEN;
offsetlen -= LDP_LSRID_IDX_LEN;
len = offsetlen;
if (len > LDP_ENTITY_IDX_LEN)
len = LDP_ENTITY_IDX_LEN;
if (len >= LDP_ENTITY_IDX_LEN)
*entityIndex = offset[0];
offset += LDP_ENTITY_IDX_LEN;
offsetlen -= LDP_ENTITY_IDX_LEN;
len = offsetlen;
if (len > LDP_LSRID_IDX_LEN)
len = LDP_LSRID_IDX_LEN;
if (len >= LDP_LSRID_IDX_LEN)
oid2in_addr(offset, sizeof(struct in_addr), peerLdpId);
}
static struct ctl_nbr *
ldpPeerTable_lookup_next(int first,
struct in_addr peerLdpId)
{
struct nbr *nbr = NULL;
struct ctl_nbr *ctl_nbr = NULL;;
if (first)
nbr = nbr_get_first_ldpid();
else
nbr = nbr_get_next_ldpid(peerLdpId.s_addr);
if (nbr)
ctl_nbr = nbr_to_ctl(nbr);
return ctl_nbr;
}
static struct ctl_nbr *
ldpPeerTable_lookup(struct variable *v, oid name[],
size_t *length, int exact,
struct in_addr *entityLdpId,
uint32_t *entityIndex,
struct in_addr *peerLdpId)
{
struct ctl_nbr *ctl_nbr = NULL;
struct nbr *nbr = NULL;
int first = 0;
if (exact) {
if (*length < (long unsigned int)v->namelen
+ LDP_PEER_ENTRY_MAX_IDX_LEN)
return NULL;
ldpPeerTable_oid_to_index(
v, name, length,
entityLdpId, entityIndex, peerLdpId);
nbr = nbr_find_ldpid(peerLdpId->s_addr);
if (nbr)
ctl_nbr = nbr_to_ctl(nbr);
return ctl_nbr;
} else {
int offsetlen = *length - v->namelen;
if (offsetlen < LDP_LSRID_IDX_LEN)
first = 1;
ldpPeerTable_oid_to_index(
v, name, length,
entityLdpId, entityIndex, peerLdpId);
ctl_nbr = ldpPeerTable_lookup_next(first, *peerLdpId);
return ctl_nbr;
}
return NULL;
}
static uint8_t *ldpPeerTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t entityIndex = 0;
struct in_addr peerLdpId = {.s_addr = 0};
struct ctl_nbr *ctl_nbr;
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
&entityIndex, &peerLdpId);
if (!ctl_nbr)
return NULL;
if (!exact) {
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
entityIndex = LDP_DEFAULT_ENTITY_INDEX;
peerLdpId = ctl_nbr->id;
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = entityIndex;
oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
name[v->namelen + 11] = 0;
name[v->namelen + 12] = 0;
/* Set length */
*length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
}
switch (v->magic) {
case MPLSLDPPEERLDPID:
*var_len = 6;
memcpy(snmp_ldp_rtrid, &ctl_nbr->id, IN_ADDR_SIZE);
return snmp_ldp_rtrid;
case MPLSLDPPEERLABELDISTMETHOD:
return SNMP_INTEGER(DOWNSTREAMUNSOLICITED);
case MPLSLDPPEERPATHVECTORLIMIT:
return SNMP_INTEGER(0);
case MPLSLDPPEERTRANSPORTADDRTYPE:
if (ctl_nbr->af == AF_INET)
return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV4);
else
return SNMP_INTEGER(MPLSLDPPEERTRANSPORTADDRTYPE_IPV6);
case MPLSLDPPEERTRANSPORTADDR:
if (ctl_nbr->af == AF_INET) {
*var_len = sizeof(ctl_nbr->raddr.v4);
return ((uint8_t *)&ctl_nbr->raddr.v4);
} else {
*var_len = sizeof(ctl_nbr->raddr.v6);
return ((uint8_t *)&ctl_nbr->raddr.v6);
}
default:
return NULL;
}
return NULL;
}
static uint8_t *ldpSessionTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t entityIndex = 0;
struct in_addr peerLdpId = {.s_addr = 0};
struct ctl_nbr *ctl_nbr;
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
ctl_nbr = ldpPeerTable_lookup(v, name, length, exact, &entityLdpId,
&entityIndex, &peerLdpId);
if (!ctl_nbr)
return NULL;
if (!exact) {
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
entityIndex = LDP_DEFAULT_ENTITY_INDEX;
peerLdpId = ctl_nbr->id;
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = entityIndex;
oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
name[v->namelen + 11] = 0;
name[v->namelen + 12] = 0;
/* Set length */
*length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
}
switch (v->magic) {
case MPLSLDPSESSIONSTATELASTCHANGE:
*var_len = sizeof(time_t);
return (uint8_t *) &(ctl_nbr->uptime);
case MPLSLDPSESSIONSTATE:
switch (ctl_nbr->nbr_state) {
case NBR_STA_INITIAL:
return SNMP_INTEGER(MPLSLDPSESSIONSTATE_INITIALIZED);
case NBR_STA_OPENREC:
return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENREC);
case NBR_STA_OPENSENT:
return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPENSENT);
case NBR_STA_OPER:
return SNMP_INTEGER(MPLSLDPSESSIONSTATE_OPERATIONAL);
default:
return SNMP_INTEGER(MPLSLDPSESSIONSTATE_NONEXISTENT);
}
case MPLSLDPSESSIONROLE:
if (ldp_addrcmp(ctl_nbr->af, &ctl_nbr->laddr, &ctl_nbr->raddr)
> 0)
return SNMP_INTEGER(MPLSLDPSESSIONROLE_ACTIVE);
else
return SNMP_INTEGER(MPLSLDPSESSIONROLE_PASSIVE);
case MPLSLDPSESSIONPROTOCOLVERSION:
return SNMP_INTEGER(LDP_VERSION);
case MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM:
return SNMP_INTEGER(ctl_nbr->hold_time_remaining);
case MPLSLDPSESSIONKEEPALIVETIME:
return SNMP_INTEGER(ctl_nbr->holdtime);
case MPLSLDPSESSIONMAXPDULENGTH:
if (ctl_nbr->nbr_state == NBR_STA_OPER)
return SNMP_INTEGER(ctl_nbr->max_pdu_len);
else
return SNMP_INTEGER(LDP_MAX_LEN);
case MPLSLDPSESSIONDISCONTINUITYTIME:
return SNMP_INTEGER(0); /* not supported */
default:
return NULL;
}
return NULL;
}
static uint8_t *ldpSessionStatsTable(struct variable *v, oid name[],
size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t entityIndex = 0;
struct in_addr peerLdpId = {.s_addr = 0};
if (smux_header_table(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
struct ctl_nbr *ctl_nbr = ldpPeerTable_lookup(v, name, length, exact,
&entityLdpId, &entityIndex, &peerLdpId);
if (!ctl_nbr)
return NULL;
if (!exact) {
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
entityIndex = LDP_DEFAULT_ENTITY_INDEX;
peerLdpId = ctl_nbr->id;
/* Copy the name out */
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
name[v->namelen + 5] = 0;
name[v->namelen + 6] = entityIndex;
oid_copy_in_addr(name + v->namelen + 7, &peerLdpId);
name[v->namelen + 11] = 0;
name[v->namelen + 12] = 0;
*length = v->namelen + LDP_PEER_ENTRY_MAX_IDX_LEN;
}
switch (v->magic) {
case MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS:
return SNMP_INTEGER(ctl_nbr->stats.unknown_msg);
case MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS:
return SNMP_INTEGER(ctl_nbr->stats.unknown_tlv);
default:
return NULL;
}
return NULL;
}
static struct variable ldpe_variables[] = {
{MPLS_LDP_LSR_ID, STRING, RONLY, ldpLsrId, 3, {1, 1, 1}},
{MPLS_LDP_LSR_LOOP_DETECTION_CAPABLE, INTEGER, RONLY,
ldpLoopDetectCap, 3, {1, 1, 2}},
{MPLS_LDP_ENTITY_LAST_CHANGE, TIMESTAMP, RONLY, ldpEntityLastChange,
3, {1, 2, 1}},
{MPLS_LDP_ENTITY_INDEX_NEXT, UNSIGNED32, RONLY, ldpEntityIndexNext,
3, {1, 2, 2}},
/* MPLS LDP mplsLdpEntityTable. */
{MPLSLDPENTITYLDPID, STRING, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 1}},
{MPLSLDPENTITYINDEX, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 2}},
{MPLSLDPENTITYPROTOCOLVERSION, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 3}},
{MPLSLDPENTITYADMINSTATUS, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 4}},
{MPLSLDPENTITYOPERSTATUS, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 5}},
{MPLSLDPENTITYTCPPORT, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 6}},
{MPLSLDPENTITYUDPDSCPORT, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 7}},
{MPLSLDPENTITYMAXPDULENGTH, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 8}},
{MPLSLDPENTITYKEEPALIVEHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 9}},
{MPLSLDPENTITYHELLOHOLDTIMER, UNSIGNED32, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 10}},
{MPLSLDPENTITYINITSESSIONTHRESHOLD, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 11}},
{MPLSLDPENTITYLABELDISTMETHOD, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 12}},
{MPLSLDPENTITYLABELRETENTIONMODE, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 13}},
{MPLSLDPENTITYPATHVECTORLIMIT, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 14}},
{MPLSLDPENTITYHOPCOUNTLIMIT, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 15}},
{MPLSLDPENTITYTRANSPORTADDRKIND, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 16}},
{MPLSLDPENTITYTARGETPEER, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 17}},
{MPLSLDPENTITYTARGETPEERADDRTYPE, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 18}},
{MPLSLDPENTITYTARGETPEERADDR, STRING, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 19}},
{MPLSLDPENTITYLABELTYPE, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 20}},
{MPLSLDPENTITYDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 21}},
{MPLSLDPENTITYSTORAGETYPE, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 22}},
{MPLSLDPENTITYROWSTATUS, INTEGER, RONLY, ldpEntityTable,
5, {1, 2, 3, 1, 23}},
/* MPLS LDP mplsLdpEntityStatsTable. */
{ MPLSLDPENTITYSTATSSESSIONATTEMPTS, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 1}},
{ MPLSLDPENTITYSTATSSESSIONREJHELLO, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 2}},
{ MPLSLDPENTITYSTATSSESSIONREJAD, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 3}},
{ MPLSLDPENTITYSTATSSESSIONREJMAXPDU, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 4}},
{ MPLSLDPENTITYSTATSSESSIONREJLR, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 5}},
{ MPLSLDPENTITYSTATSBADLDPID, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 6}},
{ MPLSLDPENTITYSTATSBADPDULENGTH, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 7}},
{ MPLSLDPENTITYSTATSBADMSGLENGTH, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 8}},
{ MPLSLDPENTITYSTATSBADTLVLENGTH, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 9}},
{ MPLSLDPENTITYSTATSMALFORMEDTLV, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 10}},
{ MPLSLDPENTITYSTATSKEEPALIVEEXP, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 11}},
{ MPLSLDPENTITYSTATSSHUTDOWNRCVNOTIFY, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 12}},
{ MPLSLDPENTITYSTATSSHUTDOWNSENTNOTIFY, COUNTER32, RONLY,
ldpEntityStatsTable, 5, {1, 2, 4, 1, 13}},
/* MPLS LDP mplsLdpPeerTable */
{MPLSLDPPEERLDPID, STRING, RONLY, ldpPeerTable, 5, {1, 3, 2, 1, 1}},
{MPLSLDPPEERLABELDISTMETHOD, INTEGER, RONLY, ldpPeerTable,
5, {1, 3, 2, 1, 2}},
{MPLSLDPPEERPATHVECTORLIMIT, INTEGER, RONLY, ldpPeerTable,
5, {1, 3, 2, 1, 3}},
{MPLSLDPPEERTRANSPORTADDRTYPE, INTEGER, RONLY, ldpPeerTable,
5, {1, 3, 2, 1, 4}},
{MPLSLDPPEERTRANSPORTADDR, STRING, RONLY, ldpPeerTable,
5, {1, 3, 2, 1, 5}},
/* MPLS LDP mplsLdpSessionTable */
{MPLSLDPSESSIONSTATELASTCHANGE, TIMESTAMP, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 1}},
{MPLSLDPSESSIONSTATE, INTEGER, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 2}},
{MPLSLDPSESSIONROLE, INTEGER, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 3}},
{MPLSLDPSESSIONPROTOCOLVERSION, UNSIGNED32, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 4}},
{MPLSLDPSESSIONKEEPALIVEHOLDTIMEREM, INTEGER, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 5}},
{MPLSLDPSESSIONKEEPALIVETIME, UNSIGNED32, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 6}},
{MPLSLDPSESSIONMAXPDULENGTH, UNSIGNED32, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 7}},
{MPLSLDPSESSIONDISCONTINUITYTIME, TIMESTAMP, RONLY, ldpSessionTable,
5, {1, 3, 3, 1, 8}},
/* MPLS LDP mplsLdpSessionStatsTable */
{MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS, COUNTER32, RONLY,
ldpSessionStatsTable, 5, {1, 3, 4, 1, 1}},
{MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS, COUNTER32, RONLY,
ldpSessionStatsTable, 5, {1, 3, 4, 1, 2}},
/* MPLS LDP mplsLdpHelloAdjacencyTable. */
{MPLSLDPHELLOADJACENCYINDEX, UNSIGNED32, RONLY,
ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 1}},
{MPLSLDPHELLOADJACENCYHOLDTIMEREM, INTEGER, RONLY,
ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 2}},
{MPLSLDPHELLOADJACENCYHOLDTIME, UNSIGNED32, RONLY,
ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 3}},
{MPLSLDPHELLOADJACENCYTYPE, INTEGER, RONLY,
ldpHelloAdjacencyTable, 6, {1, 3, 5, 1, 1, 4}},
};
static struct variable lde_variables[] = {
};
static struct trap_object ldpSessionTrapList[] = {
{5, {1, 3, 3, 1, MPLSLDPSESSIONSTATE}},
{5, {1, 3, 3, 1, MPLSLDPSESSIONDISCONTINUITYTIME}},
{5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNMESTYPEERRORS}},
{5, {1, 3, 4, 1, MPLSLDPSESSIONSTATSUNKNOWNTLVERRORS}}};
/* LDP TRAP. */
#define LDPINITSESSIONTHRESHOLDEXCEEDED 1
#define LDPPATHVECTORLIMITMISMATCH 2
#define LDPSESSIONUP 3
#define LDPSESSIONDOWN 4
static void
ldpTrapSession(struct nbr * nbr, unsigned int sptrap)
{
oid index[sizeof(oid) * (LDP_PEER_ENTRY_MAX_IDX_LEN + 1)];
struct in_addr entityLdpId = {.s_addr = 0};
uint32_t entityIndex = 0;
struct in_addr peerLdpId = {.s_addr = 0};
struct ctl_nbr *ctl_nbr = nbr_to_ctl(nbr);
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
entityIndex = LDP_DEFAULT_ENTITY_INDEX;
peerLdpId = ctl_nbr->id;
oid_copy_in_addr(index, &entityLdpId);
index[4] = 0;
index[5] = 0;
index[6] = entityIndex;
oid_copy_in_addr(&index[7], &peerLdpId);
index[11] = 0;
index[12] = 0;
index[LDP_PEER_ENTRY_MAX_IDX_LEN] = 0;
smux_trap(ldpe_variables, array_size(ldpe_variables), ldp_trap_oid,
array_size(ldp_trap_oid), ldp_oid,
sizeof(ldp_oid) / sizeof(oid), index,
LDP_PEER_ENTRY_MAX_IDX_LEN + 1,
ldpSessionTrapList, array_size(ldpSessionTrapList), sptrap);
}
static void
ldpTrapSessionUp(struct nbr * nbr)
{
ldpTrapSession(nbr, LDPSESSIONUP);
}
static void
ldpTrapSessionDown(struct nbr * nbr)
{
ldpTrapSession(nbr, LDPSESSIONDOWN);
}
static int ldp_snmp_agentx_enabled(void)
{
main_imsg_compose_both(IMSG_AGENTX_ENABLED, NULL, 0);
return 0;
}
static int ldp_snmp_nbr_state_change(struct nbr * nbr, int old_state)
{
if (old_state == nbr->state)
return 0;
if (nbr->state == NBR_STA_OPER)
ldpTrapSessionUp(nbr);
else if (old_state == NBR_STA_OPER)
ldpTrapSessionDown(nbr);
return 0;
}
static int ldp_snmp_init(struct event_loop *tm)
{
hook_register(agentx_enabled, ldp_snmp_agentx_enabled);
smux_init(tm);
return 0;
}
static int ldp_snmp_register_mib(struct event_loop *tm)
{
static int registered = 0;
if (registered)
return 0;
registered = 1;
smux_init(tm);
smux_agentx_enable();
if (ldpd_process == PROC_LDE_ENGINE)
REGISTER_MIB("mibII/ldp", lde_variables, variable, ldp_oid);
else if (ldpd_process == PROC_LDP_ENGINE) {
REGISTER_MIB("mibII/ldp", ldpe_variables, variable, ldp_oid);
hook_register(ldp_nbr_state_change, ldp_snmp_nbr_state_change);
}
return 0;
}
static int ldp_snmp_module_init(void)
{
if (ldpd_process == PROC_MAIN)
hook_register(frr_late_init, ldp_snmp_init);
else
hook_register(ldp_register_mib, ldp_snmp_register_mib);
return 0;
}
FRR_MODULE_SETUP(
.name = "ldp_snmp",
.version = FRR_VERSION,
.description = "ldp AgentX SNMP module",
.init = ldp_snmp_module_init,
);