2022-08-02 14:04:25 +00:00
|
|
|
/*
|
|
|
|
* BIRD -- Simple Network Management Protocol (SNMP)
|
|
|
|
* BGP4-MIB bgpPeerTable
|
|
|
|
*
|
|
|
|
* (c) 2022 Vojtech Vilimek <vojtech.vilimek@nic.cz>
|
|
|
|
* (c) 2022 CZ.NIC z.s.p.o
|
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
|
|
*/
|
|
|
|
|
2022-08-10 15:31:32 +00:00
|
|
|
#include "snmp.h"
|
2022-11-15 15:29:03 +00:00
|
|
|
#include "snmp_utils.h"
|
2022-09-30 07:36:09 +00:00
|
|
|
#include "subagent.h"
|
|
|
|
#include "bgp_mib.h"
|
2022-08-02 14:04:25 +00:00
|
|
|
|
2023-09-11 11:06:20 +00:00
|
|
|
static inline void ip4_to_oid(struct oid *oid, ip4_addr addr);
|
|
|
|
|
2023-08-08 19:51:38 +00:00
|
|
|
/* BGP_MIB states see enum BGP_INTERNAL_STATES */
|
2022-12-17 17:16:19 +00:00
|
|
|
static const char * const debug_bgp_states[] UNUSED = {
|
2023-07-26 12:34:01 +00:00
|
|
|
[BGP_INTERNAL_INVALID] = "BGP_INTERNAL_INVALID",
|
|
|
|
[BGP_INTERNAL_BGP] = "BGP_INTERNAL_BGP",
|
|
|
|
[BGP_INTERNAL_VERSION] = "BGP_INTERNAL_VERSION",
|
|
|
|
[BGP_INTERNAL_LOCAL_AS] = "BGP_INTERNAL_LOCAL_AS",
|
|
|
|
[BGP_INTERNAL_PEER_TABLE] = "BGP_INTERNAL_PEER_TABLE",
|
|
|
|
[BGP_INTERNAL_PEER_ENTRY] = "BGP_INTERNAL_PEER_ENTRY",
|
2023-10-11 08:44:18 +00:00
|
|
|
[BGP_INTERNAL_PEER_IDENTIFIER] = "BGP_INTERNAL_PEER_IDENTIFIER",
|
2023-07-26 12:34:01 +00:00
|
|
|
[BGP_INTERNAL_STATE] = "BGP_INTERNAL_STATE",
|
|
|
|
[BGP_INTERNAL_ADMIN_STATUS] = "BGP_INTERNAL_ADMIN_STATUS",
|
|
|
|
[BGP_INTERNAL_NEGOTIATED_VERSION] = "BGP_INTERNAL_NEGOTIATED_VERSION",
|
|
|
|
[BGP_INTERNAL_LOCAL_ADDR] = "BGP_INTERNAL_LOCAL_ADDR",
|
|
|
|
[BGP_INTERNAL_LOCAL_PORT] = "BGP_INTERNAL_LOCAL_PORT",
|
|
|
|
[BGP_INTERNAL_REMOTE_ADDR] = "BGP_INTERNAL_REMOTE_ADDR",
|
|
|
|
[BGP_INTERNAL_REMOTE_PORT] = "BGP_INTERNAL_REMOTE_PORT",
|
|
|
|
[BGP_INTERNAL_REMOTE_AS] = "BGP_INTERNAL_REMOTE_AS",
|
|
|
|
[BGP_INTERNAL_RX_UPDATES] = "BGP_INTERNAL_RX_UPDATES",
|
|
|
|
[BGP_INTERNAL_TX_UPDATES] = "BGP_INTERNAL_TX_UPDATES",
|
|
|
|
[BGP_INTERNAL_RX_MESSAGES] = "BGP_INTERNAL_RX_MESSAGES",
|
|
|
|
[BGP_INTERNAL_TX_MESSAGES] = "BGP_INTERNAL_TX_MESSAGES",
|
|
|
|
[BGP_INTERNAL_LAST_ERROR] = "BGP_INTERNAL_LAST_ERROR",
|
|
|
|
[BGP_INTERNAL_FSM_TRANSITIONS] = "BGP_INTERNAL_FSM_TRANSITIONS",
|
|
|
|
[BGP_INTERNAL_FSM_ESTABLISHED_TIME] = "BGP_INTERNAL_FSM_ESTABLISHED_TIME",
|
|
|
|
[BGP_INTERNAL_RETRY_INTERVAL] = "BGP_INTERNAL_RETRY_INTERVAL",
|
|
|
|
[BGP_INTERNAL_HOLD_TIME] = "BGP_INTERNAL_HOLD_TIME",
|
|
|
|
[BGP_INTERNAL_KEEPALIVE] = "BGP_INTERNAL_KEEPALIVE",
|
|
|
|
[BGP_INTERNAL_HOLD_TIME_CONFIGURED] = "BGP_INTERNAL_HOLD_TIME_CONFIGURED",
|
|
|
|
[BGP_INTERNAL_KEEPALIVE_CONFIGURED] = "BGP_INTERNAL_KEEPALIVE_CONFIGURED",
|
|
|
|
[BGP_INTERNAL_ORIGINATION_INTERVAL] = "BGP_INTERNAL_ORIGINATION_INTERVAL",
|
2022-11-05 15:29:00 +00:00
|
|
|
[BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT] = "BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT",
|
2023-07-26 12:34:01 +00:00
|
|
|
[BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME] = "BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME",
|
2023-10-11 08:44:18 +00:00
|
|
|
[BGP_INTERNAL_PEER_TABLE_END] = "BGP_INTERNAL_PEER_TABLE_END",
|
|
|
|
[BGP_INTERNAL_IDENTIFIER] = "BGP_INTERNAL_IDENTIFIER",
|
2023-07-26 12:34:01 +00:00
|
|
|
[BGP_INTERNAL_END] = "BGP_INTERNAL_END",
|
|
|
|
[BGP_INTERNAL_NO_VALUE] = "BGP_INTERNAL_NO_VALUE",
|
2022-11-05 15:29:00 +00:00
|
|
|
};
|
|
|
|
|
2023-10-25 14:44:08 +00:00
|
|
|
static u8
|
|
|
|
bgp_get_candidate(u32 field)
|
|
|
|
{
|
|
|
|
const u8 translation_table[] = {
|
|
|
|
[SNMP_BGP_PEER_IDENTIFIER] = BGP_INTERNAL_PEER_IDENTIFIER,
|
|
|
|
[SNMP_BGP_STATE] = BGP_INTERNAL_STATE,
|
|
|
|
[SNMP_BGP_ADMIN_STATUS] = BGP_INTERNAL_ADMIN_STATUS,
|
|
|
|
[SNMP_BGP_NEGOTIATED_VERSION] = BGP_INTERNAL_NEGOTIATED_VERSION,
|
|
|
|
[SNMP_BGP_LOCAL_ADDR] = BGP_INTERNAL_LOCAL_ADDR,
|
|
|
|
[SNMP_BGP_LOCAL_PORT] = BGP_INTERNAL_LOCAL_PORT,
|
|
|
|
[SNMP_BGP_REMOTE_ADDR] = BGP_INTERNAL_REMOTE_ADDR,
|
|
|
|
[SNMP_BGP_REMOTE_PORT] = BGP_INTERNAL_REMOTE_PORT,
|
|
|
|
[SNMP_BGP_REMOTE_AS] = BGP_INTERNAL_REMOTE_AS,
|
|
|
|
[SNMP_BGP_RX_UPDATES] = BGP_INTERNAL_RX_UPDATES,
|
|
|
|
[SNMP_BGP_TX_UPDATES] = BGP_INTERNAL_TX_UPDATES,
|
|
|
|
[SNMP_BGP_RX_MESSAGES] = BGP_INTERNAL_RX_MESSAGES,
|
|
|
|
[SNMP_BGP_TX_MESSAGES] = BGP_INTERNAL_TX_MESSAGES,
|
|
|
|
[SNMP_BGP_LAST_ERROR] = BGP_INTERNAL_LAST_ERROR,
|
|
|
|
[SNMP_BGP_FSM_TRANSITIONS] = BGP_INTERNAL_FSM_TRANSITIONS,
|
|
|
|
[SNMP_BGP_FSM_ESTABLISHED_TIME] = BGP_INTERNAL_FSM_ESTABLISHED_TIME,
|
|
|
|
[SNMP_BGP_RETRY_INTERVAL] = BGP_INTERNAL_RETRY_INTERVAL,
|
|
|
|
[SNMP_BGP_HOLD_TIME] = BGP_INTERNAL_HOLD_TIME,
|
|
|
|
[SNMP_BGP_KEEPALIVE] = BGP_INTERNAL_KEEPALIVE,
|
|
|
|
[SNMP_BGP_HOLD_TIME_CONFIGURED] = BGP_INTERNAL_HOLD_TIME_CONFIGURED,
|
|
|
|
[SNMP_BGP_KEEPALIVE_CONFIGURED] = BGP_INTERNAL_KEEPALIVE_CONFIGURED,
|
|
|
|
[SNMP_BGP_ORIGINATION_INTERVAL] = BGP_INTERNAL_ORIGINATION_INTERVAL,
|
|
|
|
[SNMP_BGP_MIN_ROUTE_ADVERTISEMENT] = BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT,
|
|
|
|
[SNMP_BGP_IN_UPDATE_ELAPSED_TIME] = BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First value is in secord cell of array translation_table, as the
|
|
|
|
* SNMP_BPG_IDENTIFIER == 1
|
|
|
|
*/
|
|
|
|
if (field > 0 && field <= ARRAY_SIZE(translation_table)- 1)
|
|
|
|
return translation_table[field];
|
|
|
|
if (field == 0)
|
|
|
|
return BGP_INTERNAL_PEER_ENTRY;
|
|
|
|
else
|
|
|
|
return BGP_INTERNAL_PEER_TABLE_END;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snmp_bgp_state - linearize oid from BGP4-MIB
|
|
|
|
* @oid: prefixed object identifier from BGP4-MIB::bgp subtree
|
|
|
|
*
|
|
|
|
* Returns linearized state for Get-PDU, GetNext-PDU and GetBulk-PDU packets.
|
|
|
|
*/
|
|
|
|
static u8
|
|
|
|
snmp_bgp_state(const struct oid *oid)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Ids of Object Identifier that are already checked:
|
|
|
|
* internet oid.prefix
|
|
|
|
* v...... v
|
|
|
|
* (*oid): .1.3.6.1.2.1.15
|
|
|
|
* -> BGP4-MIB::bgp (root)
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (snmp_is_oid_empty(oid))
|
|
|
|
return BGP_INTERNAL_END;
|
|
|
|
|
|
|
|
u8 state = BGP_INTERNAL_NO_VALUE;
|
|
|
|
|
|
|
|
u8 candidate;
|
|
|
|
switch (oid->n_subid)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
if (oid->n_subid < 2)
|
|
|
|
{
|
|
|
|
state = BGP_INTERNAL_INVALID;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Between ids[5] and ids[8] (n_subid == 9) should be IP address.
|
|
|
|
* Validity is checked later in execution because
|
|
|
|
* this field also could mean a query boundry (upper or lower).
|
|
|
|
*/
|
|
|
|
case 9:
|
|
|
|
case 8:
|
|
|
|
case 7:
|
|
|
|
case 6:
|
|
|
|
case 5:
|
|
|
|
state = bgp_get_candidate(oid->ids[4]);
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
if (oid->ids[3] == SNMP_BGP_PEER_ENTRY)
|
|
|
|
state = (state == BGP_INTERNAL_NO_VALUE) ?
|
|
|
|
BGP_INTERNAL_PEER_ENTRY : state;
|
|
|
|
else
|
|
|
|
state = BGP_INTERNAL_NO_VALUE;
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
/* u8 candidate; */
|
|
|
|
switch (oid->ids[2])
|
|
|
|
{
|
|
|
|
|
|
|
|
case SNMP_BGP_VERSION:
|
|
|
|
state = BGP_INTERNAL_VERSION;
|
|
|
|
break;
|
|
|
|
case SNMP_BGP_LOCAL_AS:
|
|
|
|
state = BGP_INTERNAL_LOCAL_AS;
|
|
|
|
break;
|
|
|
|
case SNMP_BGP_PEER_TABLE:
|
|
|
|
/* We use candidate to avoid overriding more specific state */
|
|
|
|
candidate = BGP_INTERNAL_PEER_TABLE;
|
|
|
|
break;
|
|
|
|
case SNMP_BGP_IDENTIFIER:
|
|
|
|
state = BGP_INTERNAL_IDENTIFIER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* test fails */
|
|
|
|
/* We force state invalidation */
|
|
|
|
if (oid->ids[2] < SNMP_BGP_VERSION)
|
|
|
|
{
|
|
|
|
state = BGP_INTERNAL_NO_VALUE;
|
|
|
|
candidate = BGP_INTERNAL_NO_VALUE;
|
|
|
|
}
|
|
|
|
else /* oid->ids[2] > SNMP_BGP_PEER_TABLE */
|
|
|
|
state = BGP_INTERNAL_END;
|
|
|
|
}
|
|
|
|
state = (state == BGP_INTERNAL_NO_VALUE) ?
|
|
|
|
candidate : state;
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 2: /* We found bare BGP4-MIB::bgp ObjectId */
|
|
|
|
if (state == BGP_INTERNAL_NO_VALUE ||
|
|
|
|
state == BGP_INTERNAL_INVALID)
|
|
|
|
state = BGP_INTERNAL_BGP;
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2023-10-25 14:57:46 +00:00
|
|
|
void
|
|
|
|
snmp_bgp_reg_ok(struct snmp_proto *p, struct agentx_response *r, struct oid *oid)
|
|
|
|
{
|
|
|
|
const struct oid *in_buf = ((void *) r) + sizeof(r);
|
|
|
|
int byte_ord = r->h.flags & AGENTX_NETWORK_BYTE_ORDER;
|
|
|
|
struct oid *dup = snmp_prefixize(p, in_buf, byte_ord);
|
|
|
|
|
|
|
|
ASSUME(snmp_bgp_state(oid) == snmp_bgp_state(dup));
|
|
|
|
mb_free(dup);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
snmp_bgp_reg_failed(struct snmp_proto *p, struct agentx_response UNUSED *r, struct oid UNUSED *oid)
|
|
|
|
{
|
|
|
|
snmp_stop_subagent(p);
|
|
|
|
}
|
|
|
|
|
2023-09-04 11:53:45 +00:00
|
|
|
static void
|
|
|
|
snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_error[], uint state_val)
|
|
|
|
{
|
|
|
|
// TODO remove heap allocation, put the data on stack
|
|
|
|
|
|
|
|
#define SNMP_OID_SIZE_FROM_LEN(x) (sizeof(struct oid) + (x) * sizeof(u32))
|
|
|
|
|
|
|
|
/* trap OID bgpEstablishedNotification (.1.3.6.1.2.1.0.1) */
|
2023-10-18 14:51:21 +00:00
|
|
|
struct oid *head = mb_alloc(p->pool, SNMP_OID_SIZE_FROM_LEN(3));
|
2023-09-04 11:53:45 +00:00
|
|
|
head->n_subid = 3;
|
|
|
|
head->prefix = 2;
|
|
|
|
head->include = head->pad = 0;
|
|
|
|
|
|
|
|
u32 trap_ids[] = { 1, 0, type };
|
|
|
|
for (uint i = 0; i < head->n_subid; i++)
|
|
|
|
head->ids[i] = trap_ids[i];
|
|
|
|
|
|
|
|
/* OIDs, VB type headers, octet string, ip4 address, integer */
|
|
|
|
uint sz = 3 * SNMP_OID_SIZE_FROM_LEN(9) + 3 * 4 + 8 + 8 + 4;
|
|
|
|
|
|
|
|
/* Paylaod OIDs */
|
|
|
|
|
2023-10-18 14:51:21 +00:00
|
|
|
void *data = mb_alloc(p->pool, sz);
|
2023-09-04 11:53:45 +00:00
|
|
|
struct agentx_varbind *addr_vb = data;
|
|
|
|
/* +4 for varbind header, +8 for octet string */
|
|
|
|
struct agentx_varbind *error_vb = data + SNMP_OID_SIZE_FROM_LEN(9) + 4 + 8;
|
|
|
|
struct agentx_varbind *state_vb = (void *) error_vb + SNMP_OID_SIZE_FROM_LEN(9) + 4 + 8;
|
|
|
|
|
|
|
|
addr_vb->pad = error_vb->pad = state_vb->pad = 0;
|
|
|
|
|
|
|
|
struct oid *addr = &addr_vb->name;
|
|
|
|
struct oid *error = &error_vb->name;
|
|
|
|
struct oid *state = &state_vb->name;
|
|
|
|
|
|
|
|
addr->n_subid = error->n_subid = state->n_subid = 9;
|
|
|
|
addr->prefix = error->prefix = state->prefix = 2;
|
|
|
|
addr->include = error->include = state->include = 0;
|
|
|
|
addr->pad = error->pad = state->pad = 0;
|
|
|
|
|
|
|
|
u32 oid_ids[] = {
|
|
|
|
SNMP_MIB_2, SNMP_BGP4_MIB, SNMP_BGP_PEER_TABLE, SNMP_BGP_PEER_ENTRY
|
|
|
|
};
|
|
|
|
|
|
|
|
for (uint i = 0; i < sizeof(oid_ids) / sizeof(oid_ids[0]); i++)
|
|
|
|
addr->ids[i] = error->ids[i] = state->ids[i] = oid_ids[i];
|
|
|
|
|
|
|
|
addr->ids[4] = SNMP_BGP_REMOTE_ADDR;
|
|
|
|
error->ids[4] = SNMP_BGP_LAST_ERROR;
|
|
|
|
state->ids[4] = SNMP_BGP_STATE;
|
|
|
|
|
|
|
|
for (uint i = 0; i < 4; i++)
|
|
|
|
addr->ids[5 + i] = error->ids[5 + i] = state->ids[5 + i] \
|
|
|
|
= (ip4_to_u32(ip4) >> (8 * (3-i))) & 0xFF;
|
|
|
|
|
|
|
|
snmp_varbind_ip4(addr_vb, 100, ip4);
|
|
|
|
|
|
|
|
snmp_varbind_nstr(error_vb, 100, last_error, 2);
|
|
|
|
|
|
|
|
snmp_varbind_int(state_vb, 100, state_val);
|
|
|
|
|
|
|
|
snmp_notify_pdu(p, head, data, sz, 0);
|
|
|
|
mb_free(head);
|
|
|
|
mb_free(data);
|
|
|
|
|
|
|
|
#undef SNMP_OID_SIZE_FROM_LEN
|
|
|
|
}
|
|
|
|
|
2023-09-04 11:46:02 +00:00
|
|
|
static inline uint
|
|
|
|
snmp_bgp_fsm_state(struct bgp_proto *bgp_proto)
|
|
|
|
{
|
|
|
|
const struct bgp_conn *bgp_conn = bgp_proto->conn;
|
|
|
|
const struct bgp_conn *bgp_in = &bgp_proto->incoming_conn;
|
|
|
|
const struct bgp_conn *bgp_out = &bgp_proto->outgoing_conn;
|
|
|
|
|
|
|
|
if (bgp_conn)
|
|
|
|
return bgp_conn->state;
|
|
|
|
|
|
|
|
if (MAX(bgp_in->state, bgp_out->state) == BS_CLOSE &&
|
|
|
|
MIN(bgp_in->state, bgp_out->state) != BS_CLOSE)
|
|
|
|
return MIN(bgp_in->state, bgp_out->state);
|
|
|
|
if (MIN(bgp_in->state, bgp_out->state) == BS_CLOSE)
|
|
|
|
return BS_IDLE;
|
|
|
|
|
|
|
|
return MAX(bgp_in->state, bgp_out->state);
|
|
|
|
}
|
|
|
|
|
2023-09-04 11:53:45 +00:00
|
|
|
static void
|
|
|
|
snmp_bgp_notify_wrapper(struct snmp_proto *p, struct bgp_proto *bgp, uint type)
|
|
|
|
{
|
|
|
|
// possibly dangerous
|
|
|
|
ip4_addr ip4 = ipa_to_ip4(bgp->remote_ip);
|
|
|
|
char last_error[2] = SNMP_BGP_LAST_ERROR(bgp);
|
|
|
|
uint state_val = snmp_bgp_fsm_state(bgp);
|
|
|
|
snmp_bgp_notify_common(p, type, ip4, last_error, state_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp)
|
|
|
|
{
|
|
|
|
/* .1.3.6.1.2.15.0.>1< i.e. BGP4-MIB::bgpEstablishedNotification */
|
|
|
|
snmp_bgp_notify_wrapper(p, bgp, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp)
|
|
|
|
{
|
|
|
|
/* .1.3.6.1.2.15.0.>2< i.e. BGP4-MIB::bgpBackwardTransNotification */
|
|
|
|
snmp_bgp_notify_wrapper(p, bgp, 2);
|
|
|
|
}
|
2023-09-04 11:46:02 +00:00
|
|
|
|
2022-08-02 14:04:25 +00:00
|
|
|
void
|
2022-12-10 17:08:00 +00:00
|
|
|
snmp_bgp_register(struct snmp_proto *p)
|
|
|
|
{
|
2023-09-11 11:06:20 +00:00
|
|
|
//u32 bgp_mib_prefix[] = {1, 15, 1};
|
|
|
|
u32 bgp_mib_prefix[] = { 1, 15 };
|
2022-12-10 17:08:00 +00:00
|
|
|
|
2023-08-08 19:51:38 +00:00
|
|
|
{
|
|
|
|
/* Register the whole BGP4-MIB::bgp root tree node */
|
2022-12-10 17:08:00 +00:00
|
|
|
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
|
|
|
|
2023-10-25 14:57:46 +00:00
|
|
|
struct oid *oid = mb_alloc(p->pool,
|
|
|
|
snmp_oid_sizeof(ARRAY_SIZE(bgp_mib_prefix)));
|
|
|
|
STORE_U8(oid->n_subid, ARRAY_SIZE(bgp_mib_prefix));
|
2023-09-11 11:06:20 +00:00
|
|
|
STORE_U8(oid->prefix, SNMP_MGMT);
|
2022-12-10 17:08:00 +00:00
|
|
|
|
2023-10-25 14:57:46 +00:00
|
|
|
memcpy(oid->ids, bgp_mib_prefix, sizeof(bgp_mib_prefix));
|
2022-12-10 17:08:00 +00:00
|
|
|
registering->oid = oid;
|
|
|
|
|
2023-09-11 11:06:20 +00:00
|
|
|
/* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid) */
|
|
|
|
snmp_register(p, oid, 1, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT);
|
2022-12-10 17:08:00 +00:00
|
|
|
}
|
|
|
|
}
|
2022-08-02 14:04:25 +00:00
|
|
|
|
2023-03-31 07:56:39 +00:00
|
|
|
static int
|
2022-11-05 15:29:00 +00:00
|
|
|
snmp_bgp_valid_ip4(struct oid *o)
|
|
|
|
{
|
2022-11-15 15:29:03 +00:00
|
|
|
return snmp_valid_ip4_index(o, 5);
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-08 08:27:01 +00:00
|
|
|
static inline ip4_addr
|
2022-11-05 15:29:00 +00:00
|
|
|
ip4_from_oid(const struct oid *o)
|
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
return ip4_build(
|
|
|
|
o->n_subid > 5 ? (o->ids[5] & 0xff) : 0,
|
|
|
|
o->n_subid > 6 ? (o->ids[6] & 0xff) : 0,
|
|
|
|
o->n_subid > 7 ? (o->ids[7] & 0xff) : 0,
|
|
|
|
o->n_subid > 8 ? (o->ids[8] & 0xff) : 0
|
|
|
|
);
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
2023-09-11 11:06:20 +00:00
|
|
|
static inline void
|
|
|
|
ip4_to_oid(struct oid *o, ip4_addr addr)
|
|
|
|
{
|
|
|
|
u32 tmp = ip4_to_u32(addr);
|
|
|
|
ASSUME(o->n_subid >= 9);
|
|
|
|
STORE_U32(o->ids[5], (tmp & 0xFF000000) >> 24);
|
|
|
|
STORE_U32(o->ids[6], (tmp & 0x00FF0000) >> 16);
|
|
|
|
STORE_U32(o->ids[7], (tmp & 0x0000FF00) >> 8);
|
|
|
|
STORE_U32(o->ids[8], (tmp & 0x000000FF) >> 0);
|
|
|
|
}
|
|
|
|
|
2022-12-06 15:32:26 +00:00
|
|
|
static void
|
2023-09-11 11:06:20 +00:00
|
|
|
print_bgp_record(const struct bgp_config *config)
|
2022-12-06 15:32:26 +00:00
|
|
|
{
|
|
|
|
struct proto_config *cf = (struct proto_config *) config;
|
|
|
|
struct bgp_proto *bgp_proto = (struct bgp_proto *) cf->proto;
|
|
|
|
struct bgp_conn *conn = bgp_proto->conn;
|
|
|
|
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" name: %s", cf->name);
|
2023-07-26 12:34:01 +00:00
|
|
|
snmp_log(".");
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" rem. identifier: %u", bgp_proto->remote_id);
|
|
|
|
snmp_log(" local ip: %I", config->local_ip);
|
|
|
|
snmp_log(" remote ip: %I", config->remote_ip);
|
|
|
|
snmp_log(" local port: %u", config->local_port);
|
|
|
|
snmp_log(" remote port: %u", config->remote_port);
|
2022-12-06 15:32:26 +00:00
|
|
|
|
|
|
|
if (conn) {
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" state: %u", conn->state);
|
|
|
|
snmp_log(" remote as: %u", conn->remote_caps->as4_number);
|
2022-12-06 15:32:26 +00:00
|
|
|
}
|
|
|
|
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" in updates: %u", bgp_proto->stats.rx_updates);
|
|
|
|
snmp_log(" out updates: %u", bgp_proto->stats.tx_updates);
|
|
|
|
snmp_log(" in total: %u", bgp_proto->stats.rx_messages);
|
|
|
|
snmp_log(" out total: %u", bgp_proto->stats.tx_messages);
|
|
|
|
snmp_log(" fsm transitions: %u",
|
2023-08-08 19:51:38 +00:00
|
|
|
bgp_proto->stats.fsm_established_transitions);
|
2022-12-06 15:32:26 +00:00
|
|
|
|
2023-08-08 17:45:50 +00:00
|
|
|
snmp_log(" fsm total time: -- (0)"); // not supported by bird
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" retry interval: %u", config->connect_retry_time);
|
2022-12-06 15:32:26 +00:00
|
|
|
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" hold configurated: %u", config->hold_time );
|
|
|
|
snmp_log(" keep alive config: %u", config->keepalive_time );
|
2022-12-06 15:32:26 +00:00
|
|
|
|
2023-08-08 17:45:50 +00:00
|
|
|
snmp_log(" min AS origin. int.: -- (0)"); // not supported by bird
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" min route advertisement: %u", 0 );
|
|
|
|
snmp_log(" in update elapsed time: %u", 0 );
|
2022-12-06 15:32:26 +00:00
|
|
|
|
|
|
|
if (!conn)
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" no connection established");
|
2022-12-06 15:32:26 +00:00
|
|
|
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log(" outgoinin_conn state %u", bgp_proto->outgoing_conn.state + 1);
|
|
|
|
snmp_log(" incoming_conn state: %u", bgp_proto->incoming_conn.state + 1);
|
2022-12-06 15:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_bgp_record_all(struct snmp_proto *p)
|
|
|
|
{
|
2022-12-10 12:22:37 +00:00
|
|
|
snmp_log("dumping watched bgp status");
|
2022-12-06 15:32:26 +00:00
|
|
|
HASH_WALK(p->bgp_hash, next, peer)
|
|
|
|
{
|
|
|
|
print_bgp_record(peer->config);
|
|
|
|
}
|
|
|
|
HASH_WALK_END;
|
2022-12-17 17:16:19 +00:00
|
|
|
snmp_log("dumping watched end");
|
2022-12-06 15:32:26 +00:00
|
|
|
}
|
|
|
|
|
2023-09-04 07:25:51 +00:00
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
static inline int
|
2022-11-05 15:29:00 +00:00
|
|
|
is_dynamic(u8 state)
|
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
return (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
|
2022-11-05 15:29:00 +00:00
|
|
|
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME);
|
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
static inline int
|
|
|
|
is_static(u8 state)
|
|
|
|
{
|
|
|
|
return (state == BGP_INTERNAL_VERSION ||
|
|
|
|
state == BGP_INTERNAL_LOCAL_AS ||
|
|
|
|
state == BGP_INTERNAL_IDENTIFIER);
|
|
|
|
}
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
static inline int
|
|
|
|
snmp_bgp_has_value(u8 state)
|
|
|
|
{
|
|
|
|
if (state <= BGP_INTERNAL_BGP ||
|
|
|
|
state == BGP_INTERNAL_PEER_TABLE ||
|
2022-11-15 15:29:03 +00:00
|
|
|
state == BGP_INTERNAL_PEER_ENTRY ||
|
2023-10-11 08:44:18 +00:00
|
|
|
state == BGP_INTERNAL_PEER_TABLE_END ||
|
2023-07-26 12:02:23 +00:00
|
|
|
state >= BGP_INTERNAL_END)
|
|
|
|
return 0;
|
2022-11-05 15:29:00 +00:00
|
|
|
else
|
2023-07-26 12:02:23 +00:00
|
|
|
return 1;
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snmp_bgp_get_valid - only states with valid value
|
|
|
|
* @state: BGP linearized state
|
|
|
|
*
|
|
|
|
* Returns @state if has value in BGP4-MIB, zero otherwise. Used for Get-PDU
|
2023-03-31 07:56:39 +00:00
|
|
|
* ackets.
|
2022-11-05 15:29:00 +00:00
|
|
|
*/
|
|
|
|
u8
|
|
|
|
snmp_bgp_get_valid(u8 state)
|
|
|
|
{
|
2023-08-08 19:51:38 +00:00
|
|
|
if (state == BGP_INTERNAL_INVALID ||
|
|
|
|
state == BGP_INTERNAL_BGP ||
|
|
|
|
state == BGP_INTERNAL_PEER_TABLE ||
|
|
|
|
state == BGP_INTERNAL_PEER_ENTRY ||
|
2023-10-11 08:44:18 +00:00
|
|
|
state == BGP_INTERNAL_PEER_TABLE_END ||
|
2023-08-08 19:51:38 +00:00
|
|
|
state >= BGP_INTERNAL_END)
|
2022-11-05 15:29:00 +00:00
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snmp_bgp_next_state - next state that has value
|
|
|
|
* @state: BGP linearized state
|
|
|
|
*
|
|
|
|
* Returns successor state of @state with valid value in BG4-MIB. Used for
|
|
|
|
* GetNext-PDU and GetBulk-PDU packets.
|
|
|
|
*/
|
|
|
|
u8
|
|
|
|
snmp_bgp_next_state(u8 state)
|
|
|
|
{
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case BGP_INTERNAL_LOCAL_AS:
|
|
|
|
case BGP_INTERNAL_PEER_TABLE:
|
|
|
|
case BGP_INTERNAL_PEER_ENTRY:
|
2023-10-11 08:44:18 +00:00
|
|
|
return BGP_INTERNAL_PEER_IDENTIFIER;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
|
|
|
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
|
2023-10-11 08:44:18 +00:00
|
|
|
case BGP_INTERNAL_PEER_TABLE_END:
|
|
|
|
return BGP_INTERNAL_IDENTIFIER;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_IDENTIFIER:
|
2022-11-05 15:29:00 +00:00
|
|
|
case BGP_INTERNAL_END:
|
|
|
|
return BGP_INTERNAL_END;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return state + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 12:28:57 +00:00
|
|
|
int
|
|
|
|
snmp_bgp_is_supported(struct oid *o)
|
2022-08-02 14:12:09 +00:00
|
|
|
{
|
2022-09-30 07:36:09 +00:00
|
|
|
if (o->prefix == 2 && o->n_subid > 0 && o->ids[0] == 1)
|
2022-09-20 12:28:57 +00:00
|
|
|
{
|
2023-08-08 17:45:50 +00:00
|
|
|
if (o->n_subid == 2 && (o->ids[1] == SNMP_BGP4_MIB ||
|
|
|
|
o->ids[1] == SNMP_BGP_LOCAL_AS))
|
2022-09-20 12:28:57 +00:00
|
|
|
return 1;
|
2023-08-08 17:45:50 +00:00
|
|
|
else if (o->n_subid > 2 && o->ids[1] == SNMP_BGP_PEER_TABLE &&
|
|
|
|
o->ids[2] == SNMP_BGP_PEER_ENTRY)
|
2022-09-30 07:36:09 +00:00
|
|
|
{
|
2023-08-08 19:51:38 +00:00
|
|
|
if (o->n_subid == 3)
|
|
|
|
return 1;
|
|
|
|
if (o->n_subid == 8 && o->ids[3] > 0)
|
|
|
|
return 1;
|
2022-09-30 07:36:09 +00:00
|
|
|
}
|
2023-08-08 19:51:38 +00:00
|
|
|
return 0;
|
2022-09-20 12:28:57 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
static int
|
|
|
|
oid_state_compare(const struct oid *oid, u8 state)
|
|
|
|
{
|
|
|
|
ASSUME(oid != NULL);
|
2023-10-11 08:44:18 +00:00
|
|
|
if (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
|
2023-07-26 12:02:23 +00:00
|
|
|
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME)
|
|
|
|
return (oid->n_subid > 9) - (oid->n_subid < 9);
|
2023-10-11 08:44:18 +00:00
|
|
|
if ((state >= BGP_INTERNAL_VERSION && state <= BGP_INTERNAL_PEER_TABLE) ||
|
|
|
|
(state == BGP_INTERNAL_IDENTIFIER))
|
2023-07-26 12:02:23 +00:00
|
|
|
return (oid->n_subid > 3) - (oid->n_subid < 3);
|
|
|
|
if (state == BGP_INTERNAL_PEER_ENTRY)
|
|
|
|
return (oid->n_subid > 4) - (oid->n_subid < 4);
|
|
|
|
if (state == BGP_INTERNAL_BGP)
|
|
|
|
return (oid->n_subid > 2) - (oid->n_subid < 2);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
static struct oid *
|
|
|
|
update_bgp_oid(struct oid *oid, u8 state)
|
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
if (state == BGP_INTERNAL_END || state == BGP_INTERNAL_INVALID ||
|
|
|
|
state == BGP_INTERNAL_NO_VALUE)
|
|
|
|
return oid;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-09-04 07:25:51 +00:00
|
|
|
/* No need to reallocate anything if the OID has same lin. state */
|
2022-11-05 15:29:00 +00:00
|
|
|
if (snmp_bgp_state(oid) == state)
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
if (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
|
2023-07-26 12:02:23 +00:00
|
|
|
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME &&
|
|
|
|
oid->n_subid == 9)
|
|
|
|
return oid;
|
|
|
|
if (state >= BGP_INTERNAL_VERSION &&
|
|
|
|
state <= BGP_INTERNAL_PEER_TABLE && oid->n_subid == 3)
|
|
|
|
return oid;
|
|
|
|
if (state == BGP_INTERNAL_PEER_ENTRY && oid->n_subid == 4)
|
|
|
|
return oid;
|
|
|
|
if (state == BGP_INTERNAL_BGP && oid->n_subid == 2)
|
|
|
|
return oid;
|
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case BGP_INTERNAL_BGP:
|
2023-08-08 19:51:38 +00:00
|
|
|
/* This could potentially destroy same old data */
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid->n_subid != 2)
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(2));
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
oid->n_subid = 2;
|
2023-08-08 19:51:38 +00:00
|
|
|
oid->ids[0] = SNMP_MIB_2;
|
2022-11-05 15:29:00 +00:00
|
|
|
oid->ids[1] = SNMP_BGP4_MIB;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_VERSION:
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid->n_subid != 3)
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
oid->n_subid = 3;
|
|
|
|
oid->ids[2] = SNMP_BGP_VERSION;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_LOCAL_AS:
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid->n_subid != 3)
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
|
|
|
|
|
|
|
oid->n_subid = 3;
|
2023-08-08 19:51:38 +00:00
|
|
|
oid->ids[2] = SNMP_BGP_LOCAL_AS;
|
2022-11-05 15:29:00 +00:00
|
|
|
break;
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
case BGP_INTERNAL_PEER_IDENTIFIER:
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid->n_subid != 9)
|
|
|
|
{
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(9));
|
|
|
|
|
|
|
|
if (oid->n_subid < 6)
|
|
|
|
oid->ids[5] = 0;
|
|
|
|
if (oid->n_subid < 7)
|
|
|
|
oid->ids[6] = 0;
|
|
|
|
if (oid->n_subid < 8)
|
|
|
|
oid->ids[7] = 0;
|
|
|
|
if (oid->n_subid < 9)
|
|
|
|
oid->ids[8] = 0;
|
|
|
|
}
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
oid->ids[2] = SNMP_BGP_PEER_TABLE;
|
|
|
|
oid->ids[3] = SNMP_BGP_PEER_ENTRY;
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
oid->ids[4] = SNMP_BGP_PEER_IDENTIFIER;
|
2023-07-26 12:02:23 +00:00
|
|
|
oid->n_subid = 9;
|
2022-11-05 15:29:00 +00:00
|
|
|
break;
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
#define SNMP_UPDATE_CASE(num, update) \
|
|
|
|
case num: \
|
|
|
|
if (oid->n_subid != 9) \
|
|
|
|
{ \
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(9)); \
|
|
|
|
\
|
|
|
|
if (oid->n_subid < 6) \
|
|
|
|
oid->ids[5] = 0; \
|
|
|
|
if (oid->n_subid < 7) \
|
|
|
|
oid->ids[6] = 0; \
|
|
|
|
if (oid->n_subid < 8) \
|
|
|
|
oid->ids[7] = 0; \
|
|
|
|
if (oid->n_subid < 9) \
|
|
|
|
oid->ids[8] = 0; \
|
|
|
|
} \
|
|
|
|
oid->n_subid = 9; \
|
|
|
|
oid->ids[4] = update; \
|
2022-11-05 15:29:00 +00:00
|
|
|
break;
|
|
|
|
|
2023-03-14 13:09:45 +00:00
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_STATE, SNMP_BGP_STATE)
|
2022-11-05 15:29:00 +00:00
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_ADMIN_STATUS, SNMP_BGP_ADMIN_STATUS)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_NEGOTIATED_VERSION, SNMP_BGP_NEGOTIATED_VERSION)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_LOCAL_ADDR, SNMP_BGP_LOCAL_ADDR)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_LOCAL_PORT, SNMP_BGP_LOCAL_PORT)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_REMOTE_ADDR, SNMP_BGP_REMOTE_ADDR)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_REMOTE_PORT, SNMP_BGP_REMOTE_PORT)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_REMOTE_AS, SNMP_BGP_REMOTE_AS)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_RX_UPDATES, SNMP_BGP_RX_UPDATES)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_TX_UPDATES, SNMP_BGP_TX_UPDATES)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_RX_MESSAGES, SNMP_BGP_RX_MESSAGES)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_TX_MESSAGES, SNMP_BGP_TX_MESSAGES)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_LAST_ERROR, SNMP_BGP_LAST_ERROR)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_FSM_TRANSITIONS, SNMP_BGP_FSM_TRANSITIONS)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_FSM_ESTABLISHED_TIME, SNMP_BGP_FSM_ESTABLISHED_TIME)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_RETRY_INTERVAL, SNMP_BGP_RETRY_INTERVAL)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_HOLD_TIME, SNMP_BGP_HOLD_TIME)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_KEEPALIVE, SNMP_BGP_KEEPALIVE)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_HOLD_TIME_CONFIGURED, SNMP_BGP_HOLD_TIME_CONFIGURED)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_KEEPALIVE_CONFIGURED, SNMP_BGP_KEEPALIVE_CONFIGURED)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_ORIGINATION_INTERVAL, SNMP_BGP_ORIGINATION_INTERVAL)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT, SNMP_BGP_MIN_ROUTE_ADVERTISEMENT)
|
|
|
|
|
|
|
|
SNMP_UPDATE_CASE(BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME, SNMP_BGP_IN_UPDATE_ELAPSED_TIME)
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
case BGP_INTERNAL_IDENTIFIER:
|
|
|
|
if (oid->n_subid != 3)
|
|
|
|
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
|
|
|
|
|
|
|
oid->n_subid = 3;
|
|
|
|
oid->ids[2] = 4;
|
|
|
|
break;
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
default:
|
2023-08-08 19:51:38 +00:00
|
|
|
/* intentionally left blank */
|
|
|
|
break;
|
2023-09-04 07:25:51 +00:00
|
|
|
//die("update unavailable");
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return oid;
|
|
|
|
#undef SNMP_UPDATE_CASE
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO test bgp_find_dynamic_oid
|
|
|
|
static struct oid *
|
2023-07-26 12:02:23 +00:00
|
|
|
bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, const struct oid *o_end, u8 start_state)
|
2022-11-05 15:29:00 +00:00
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
ASSUME(o_start != NULL);
|
|
|
|
ASSUME(o_end != NULL);
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
ip4_addr ip4 = ip4_from_oid(o_start);
|
2023-07-26 12:02:23 +00:00
|
|
|
ip4_addr dest;
|
|
|
|
|
|
|
|
if (o_start->n_subid < 9)
|
|
|
|
o_start->include = 1;
|
|
|
|
|
|
|
|
int check_dest = snmp_is_oid_empty(o_end);
|
|
|
|
if (check_dest)
|
|
|
|
{
|
|
|
|
u8 end_state = snmp_bgp_state(o_end);
|
|
|
|
dest = (start_state == end_state && o_end->n_subid > 5) ?
|
|
|
|
ip4_from_oid(o_end) :
|
2023-08-08 19:51:38 +00:00
|
|
|
ip4_from_u32(UINT32_MAX);
|
2023-07-26 12:02:23 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
net_addr net;
|
|
|
|
net_fill_ip4(&net, ip4, IP4_MAX_PREFIX_LENGTH);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
struct f_trie_walk_state ws;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
trie_walk_init(&ws, p->bgp_trie, NULL, 0);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-08-08 19:51:38 +00:00
|
|
|
if (trie_walk_next(&ws, &net))
|
2022-11-05 15:29:00 +00:00
|
|
|
{
|
2023-03-31 07:56:39 +00:00
|
|
|
/*
|
2023-08-08 19:51:38 +00:00
|
|
|
* If the o_end is empty, then there are no conditions on the ip4 address.
|
2023-03-31 07:56:39 +00:00
|
|
|
*/
|
2023-07-26 12:02:23 +00:00
|
|
|
int cmp = ip4_compare(net4_prefix(&net), dest);
|
2023-03-31 07:56:39 +00:00
|
|
|
if (cmp < 0 || (cmp == 0 && snmp_is_oid_empty(o_end)))
|
2022-12-17 17:16:19 +00:00
|
|
|
{
|
2023-09-04 11:58:59 +00:00
|
|
|
// TODO repair
|
2023-10-18 14:51:21 +00:00
|
|
|
struct oid *o = snmp_oid_duplicate(p->pool, o_start);
|
2023-07-26 12:02:23 +00:00
|
|
|
snmp_oid_ip4_index(o, 5, net4_prefix(&net));
|
2022-12-17 17:16:19 +00:00
|
|
|
|
|
|
|
return o;
|
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
static struct oid *
|
|
|
|
search_bgp_dynamic(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid
|
2023-10-18 16:06:24 +00:00
|
|
|
UNUSED, u8 next_state)
|
2022-11-05 15:29:00 +00:00
|
|
|
{
|
2023-03-24 14:01:35 +00:00
|
|
|
struct oid *o_copy = o_start;
|
2023-07-26 12:34:01 +00:00
|
|
|
do
|
|
|
|
{
|
2023-03-24 14:01:35 +00:00
|
|
|
o_start = o_copy = update_bgp_oid(o_copy, next_state);
|
2022-11-15 15:29:03 +00:00
|
|
|
|
|
|
|
o_start = bgp_find_dynamic_oid(p, o_start, o_end, next_state);
|
|
|
|
|
|
|
|
next_state = snmp_bgp_next_state(next_state);
|
2023-09-04 07:25:51 +00:00
|
|
|
/* The search in next state is done from beginning. */
|
2023-07-26 12:02:23 +00:00
|
|
|
o_start->ids[5] = o_start->ids[6] = o_start->ids[7] = o_start->ids[8] = 0;
|
|
|
|
o_start->include = 1;
|
2022-11-15 15:29:03 +00:00
|
|
|
|
|
|
|
} while (o_start == NULL && next_state < BGP_INTERNAL_END);
|
|
|
|
|
|
|
|
return o_start;
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
/**
|
|
|
|
* snmp_bgp_find_next_oid - walk bgp peer addresses and update @o_start oid
|
|
|
|
*
|
|
|
|
* @p:
|
|
|
|
* @oid:
|
|
|
|
* @contid:
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
snmp_bgp_find_next_oid(struct snmp_proto *p, struct oid *oid, uint UNUSED contid)
|
|
|
|
{
|
|
|
|
ip4_addr ip4 = ip4_from_oid(oid);
|
|
|
|
//ip_add4 dest = ip4_from_u32(0xFFFFFFFF);
|
|
|
|
|
|
|
|
net_addr net;
|
|
|
|
net_fill_ip4(&net, ip4, IP4_MAX_PREFIX_LENGTH);
|
|
|
|
struct f_trie_walk_state ws;
|
|
|
|
|
|
|
|
int match = trie_walk_init(&ws, p->bgp_trie, &net, 1);
|
|
|
|
|
|
|
|
if (match && oid->include)
|
|
|
|
{
|
|
|
|
oid->include = 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We skip the first match as we should not include ip address in oid */
|
|
|
|
if (match)
|
|
|
|
{
|
|
|
|
trie_walk_next(&ws, &net);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trie_walk_next(&ws, &net))
|
|
|
|
{
|
|
|
|
u32 res = ipa_to_u32(net_prefix(&net));
|
|
|
|
|
|
|
|
ASSUME(oid->n_subid == 9);
|
|
|
|
oid->ids[5] = (res & 0xFF000000) >> 24;
|
|
|
|
oid->ids[6] = (res & 0x00FF0000) >> 16;
|
|
|
|
oid->ids[7] = (res & 0x0000FF00) >> 8;
|
|
|
|
oid->ids[8] = (res & 0x000000FF) >> 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum snmp_search_res
|
|
|
|
snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint UNUSED contid, u8 next_state)
|
|
|
|
{
|
|
|
|
struct oid *oid = *searched;
|
2023-10-11 08:44:18 +00:00
|
|
|
u8 end_state = MIN(snmp_bgp_state(o_end), BGP_INTERNAL_PEER_TABLE_END);
|
2023-07-26 12:02:23 +00:00
|
|
|
|
|
|
|
ASSUME(end_state <= BGP_INTERNAL_END);
|
|
|
|
ASSUME(oid != NULL);
|
|
|
|
|
|
|
|
oid = update_bgp_oid(oid, next_state);
|
|
|
|
|
|
|
|
int found;
|
|
|
|
while (!(found = snmp_bgp_find_next_oid(p, oid, contid)) && next_state <= end_state)
|
|
|
|
{
|
|
|
|
next_state = snmp_bgp_next_state(next_state);
|
2023-10-11 08:44:18 +00:00
|
|
|
if (next_state == BGP_INTERNAL_IDENTIFIER)
|
2023-07-26 12:02:23 +00:00
|
|
|
break;
|
|
|
|
oid = update_bgp_oid(oid, next_state);
|
2023-08-08 19:51:38 +00:00
|
|
|
/* In case of search for next bgp state, we want to start from beginning. */
|
2023-07-26 12:02:23 +00:00
|
|
|
oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0;
|
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
if (next_state < BGP_INTERNAL_PEER_TABLE_END && next_state <= end_state)
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
|
|
|
*searched = oid;
|
|
|
|
return SNMP_SEARCH_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SNMP_SEARCH_END_OF_VIEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum snmp_search_res
|
|
|
|
snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid)
|
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
enum snmp_search_res r = SNMP_SEARCH_END_OF_VIEW;
|
2023-07-26 12:02:23 +00:00
|
|
|
u8 bgp_state = snmp_bgp_state(*searched);
|
2023-10-11 08:44:18 +00:00
|
|
|
u8 state;
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-09-04 07:25:51 +00:00
|
|
|
if (bgp_state == BGP_INTERNAL_END)
|
|
|
|
{
|
|
|
|
return SNMP_SEARCH_NO_OBJECT;
|
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
if (is_static(bgp_state) && (*searched)->include)
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
return SNMP_SEARCH_OK;
|
2023-07-26 12:02:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
state = snmp_bgp_next_state(bgp_state);
|
|
|
|
if (is_static(state) && !is_dynamic(bgp_state))
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
*searched = update_bgp_oid(*searched, state);
|
|
|
|
return SNMP_SEARCH_OK;
|
|
|
|
}
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
if (is_dynamic(state) && !is_dynamic(bgp_state))
|
|
|
|
{
|
|
|
|
for (uint i = 5; i < MIN(9, (*searched)->n_subid); i++)
|
|
|
|
(*searched)->ids[i] = 0;
|
|
|
|
r = snmp_bgp_search_dynamic(p, searched, o_end, contid, state);
|
|
|
|
if (r != SNMP_SEARCH_END_OF_VIEW)
|
|
|
|
return r;
|
2023-07-26 12:02:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is_dynamic(bgp_state))
|
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
r = snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
|
|
|
|
|
|
|
|
if (r != SNMP_SEARCH_END_OF_VIEW)
|
|
|
|
return r;
|
2023-07-26 12:02:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
state = snmp_bgp_next_state(bgp_state);
|
|
|
|
if (state <= BGP_INTERNAL_IDENTIFIER)
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
*searched = update_bgp_oid(*searched, state);
|
2023-07-26 12:02:23 +00:00
|
|
|
return SNMP_SEARCH_OK;
|
|
|
|
}
|
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
// TODO add route table
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
/* end not found */
|
2023-07-26 12:02:23 +00:00
|
|
|
return SNMP_SEARCH_END_OF_VIEW;
|
|
|
|
}
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
struct oid *
|
2023-07-26 12:02:23 +00:00
|
|
|
snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid UNUSED)
|
2022-11-05 15:29:00 +00:00
|
|
|
{
|
|
|
|
u8 start_state = snmp_bgp_state(o_start);
|
2023-09-04 07:25:51 +00:00
|
|
|
|
|
|
|
// print debugging information
|
2022-12-06 15:32:26 +00:00
|
|
|
print_bgp_record_all(p);
|
|
|
|
|
2022-11-05 15:29:00 +00:00
|
|
|
if (o_start->include && snmp_bgp_has_value(start_state) &&
|
|
|
|
!is_dynamic(start_state) && o_start->n_subid == 3)
|
|
|
|
{
|
2023-08-08 19:51:38 +00:00
|
|
|
/* We disable including for next time searching. */
|
|
|
|
o_start->include = 0;
|
2022-11-05 15:29:00 +00:00
|
|
|
return o_start;
|
|
|
|
}
|
2023-03-24 14:01:35 +00:00
|
|
|
else if (o_start->include && snmp_bgp_has_value(start_state) &&
|
2023-07-26 12:02:23 +00:00
|
|
|
is_dynamic(start_state))
|
2023-03-24 14:01:35 +00:00
|
|
|
return search_bgp_dynamic(p, o_start, o_end, contid, start_state);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-09-04 07:25:51 +00:00
|
|
|
/* o_start is not inclusive */
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-03-24 14:01:35 +00:00
|
|
|
u8 next_state = snmp_bgp_next_state(start_state);
|
|
|
|
// TODO more checks ?!?
|
|
|
|
if (!is_dynamic(next_state))
|
|
|
|
{
|
|
|
|
o_start = update_bgp_oid(o_start, next_state);
|
|
|
|
return o_start;
|
2022-11-15 15:29:03 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-03-24 14:01:35 +00:00
|
|
|
/* is_dynamic(next_state) == 1 */
|
|
|
|
|
2023-08-08 19:51:38 +00:00
|
|
|
return search_bgp_dynamic(p, o_start, o_end, 0, next_state);
|
2022-11-15 15:29:03 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
static byte *
|
2023-07-26 12:02:23 +00:00
|
|
|
bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
|
2023-09-11 11:06:20 +00:00
|
|
|
struct snmp_pdu *c, u8 state)
|
2022-11-15 15:29:03 +00:00
|
|
|
{
|
2022-11-19 22:00:02 +00:00
|
|
|
struct oid *oid = &vb->name;
|
2023-07-26 12:02:23 +00:00
|
|
|
uint size = c->size - snmp_varbind_header_size(vb);
|
|
|
|
byte *pkt;
|
2022-11-15 15:29:03 +00:00
|
|
|
|
|
|
|
ip_addr addr;
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid_state_compare(oid, state) == 0 && snmp_bgp_valid_ip4(oid))
|
2022-11-15 15:29:03 +00:00
|
|
|
addr = ipa_from_ip4(ip4_from_oid(oid));
|
|
|
|
else
|
2022-11-19 22:00:02 +00:00
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
|
|
|
pkt = ((byte *) vb) + snmp_varbind_header_size(vb);
|
2022-11-19 22:00:02 +00:00
|
|
|
return pkt;
|
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-09-04 07:25:51 +00:00
|
|
|
// TODO XXX deal with possible change of (remote) ip; BGP should restart and
|
|
|
|
// disappear
|
2022-11-15 15:29:03 +00:00
|
|
|
struct snmp_bgp_peer *pe = HASH_FIND(p->bgp_hash, SNMP_HASH, addr);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
struct bgp_proto *bgp_proto = NULL;
|
|
|
|
struct proto *proto = NULL;
|
|
|
|
if (pe)
|
|
|
|
{
|
|
|
|
proto = ((struct proto_config *) pe->config)->proto;
|
|
|
|
if (proto->proto == &proto_bgp &&
|
2023-07-26 12:02:23 +00:00
|
|
|
ipa_equal(addr, ((struct bgp_proto *) proto)->remote_ip))
|
2022-11-15 15:29:03 +00:00
|
|
|
{
|
|
|
|
bgp_proto = (struct bgp_proto *) proto;
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
2023-08-08 19:51:38 +00:00
|
|
|
/* We did not found binded BGP protocol. */
|
2022-11-15 15:29:03 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
die("Binded bgp protocol not found!");
|
2023-07-26 12:02:23 +00:00
|
|
|
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
|
|
|
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
2022-11-15 15:29:03 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-19 22:00:02 +00:00
|
|
|
else
|
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
|
|
|
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
2022-11-19 22:00:02 +00:00
|
|
|
}
|
|
|
|
|
2023-09-04 11:53:45 +00:00
|
|
|
const struct bgp_conn *bgp_conn = bgp_proto->conn;
|
|
|
|
const struct bgp_stats *bgp_stats = &bgp_proto->stats;
|
2022-11-15 15:29:03 +00:00
|
|
|
const struct bgp_config *bgp_conf = bgp_proto->cf;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-09-04 11:46:02 +00:00
|
|
|
uint bgp_state = snmp_bgp_fsm_state(bgp_proto);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-09-04 11:46:02 +00:00
|
|
|
char last_error[2] = SNMP_BGP_LAST_ERROR(bgp_proto);
|
2022-11-15 15:29:03 +00:00
|
|
|
switch (state)
|
2022-11-05 15:29:00 +00:00
|
|
|
{
|
2023-10-11 08:44:18 +00:00
|
|
|
case BGP_INTERNAL_PEER_IDENTIFIER:
|
2022-11-15 15:29:03 +00:00
|
|
|
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
|
2023-08-08 17:45:50 +00:00
|
|
|
pkt = snmp_varbind_ip4(vb, size, ip4_from_u32(bgp_proto->remote_id));
|
2022-11-15 15:29:03 +00:00
|
|
|
else
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_ip4(vb, size, IP4_NONE);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_STATE:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_state);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_ADMIN_STATUS:
|
|
|
|
if (proto->disabled)
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, AGENTX_ADMIN_STOP);
|
2022-11-15 15:29:03 +00:00
|
|
|
else
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, AGENTX_ADMIN_START);
|
2022-11-15 15:29:03 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_NEGOTIATED_VERSION:
|
|
|
|
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, SNMP_BGP_NEGOTIATED_VER_VALUE);
|
2022-11-15 15:29:03 +00:00
|
|
|
else
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, SNMP_BGP_NEGOTIATED_VER_NO_VALUE);
|
2022-11-15 15:29:03 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_LOCAL_ADDR:
|
|
|
|
// TODO XXX bgp_proto->link_addr & zero local_ip
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(bgp_proto->local_ip));
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_LOCAL_PORT:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_conf->local_port);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_REMOTE_ADDR:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(bgp_proto->remote_ip));
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_REMOTE_PORT:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_conf->remote_port);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_REMOTE_AS:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_proto->remote_as);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* IN UPDATES */
|
|
|
|
case BGP_INTERNAL_RX_UPDATES:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_counter32(vb, size, bgp_stats->rx_updates);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* OUT UPDATES */
|
|
|
|
case BGP_INTERNAL_TX_UPDATES:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_counter32(vb, size, bgp_stats->tx_updates);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* IN MESSAGES */
|
|
|
|
case BGP_INTERNAL_RX_MESSAGES:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_counter32(vb, size, bgp_stats->rx_messages);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* OUT MESSAGES */
|
|
|
|
case BGP_INTERNAL_TX_MESSAGES:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_counter32(vb, size, bgp_stats->tx_messages);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_LAST_ERROR:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_nstr(vb, size, last_error, 2);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_FSM_TRANSITIONS:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_counter32(vb, size,
|
|
|
|
bgp_stats->fsm_established_transitions);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_FSM_ESTABLISHED_TIME:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_gauge32(vb, size,
|
|
|
|
(current_time() - bgp_proto->last_established) TO_S);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_RETRY_INTERVAL:
|
2023-03-24 14:01:35 +00:00
|
|
|
// retry interval != 0
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_conf->connect_retry_time);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_HOLD_TIME:
|
2023-03-24 14:01:35 +00:00
|
|
|
// (0, 3..65535)
|
2023-08-08 17:45:50 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, (bgp_conn) ? bgp_conn->hold_time : 0);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_KEEPALIVE:
|
2023-08-08 17:45:50 +00:00
|
|
|
if (!bgp_conf->hold_time)
|
|
|
|
pkt = snmp_varbind_int(vb, size, 0);
|
|
|
|
else
|
|
|
|
pkt = snmp_varbind_int(vb, size,
|
|
|
|
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_HOLD_TIME_CONFIGURED:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, bgp_conf->hold_time);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_KEEPALIVE_CONFIGURED:
|
2023-08-08 17:45:50 +00:00
|
|
|
if (!bgp_conf->keepalive_time)
|
|
|
|
pkt = snmp_varbind_int(vb, size, 0);
|
|
|
|
else
|
|
|
|
pkt = snmp_varbind_int(vb, size,
|
|
|
|
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_ORIGINATION_INTERVAL:
|
2023-07-26 12:02:23 +00:00
|
|
|
// (1..65535) but is not supported
|
|
|
|
pkt = snmp_varbind_int(vb, size, 0);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT:
|
2023-07-26 12:02:23 +00:00
|
|
|
// (1..65535) but is not supported
|
|
|
|
pkt = snmp_varbind_int(vb, size, 0);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
|
2023-08-08 17:45:50 +00:00
|
|
|
pkt = snmp_varbind_gauge32(vb, size,
|
|
|
|
(current_time() - bgp_proto->last_rx_update) TO_S
|
|
|
|
);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2023-03-24 14:01:35 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_END:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_INVALID:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_BGP:
|
|
|
|
break;
|
|
|
|
case BGP_INTERNAL_PEER_TABLE:
|
|
|
|
break;
|
|
|
|
case BGP_INTERNAL_PEER_ENTRY:
|
|
|
|
break;
|
|
|
|
case BGP_INTERNAL_NO_VALUE:
|
|
|
|
break;
|
2022-11-05 15:29:00 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
if (!pkt)
|
|
|
|
{
|
|
|
|
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
|
|
|
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
|
|
|
}
|
|
|
|
|
2022-11-19 22:00:02 +00:00
|
|
|
return pkt;
|
2022-11-15 15:29:03 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
static byte *
|
2022-11-19 22:00:02 +00:00
|
|
|
bgp_fill_static(struct snmp_proto *p, struct agentx_varbind *vb, byte *pkt, uint size
|
2022-11-15 15:29:03 +00:00
|
|
|
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
|
|
|
{
|
2023-10-18 16:06:24 +00:00
|
|
|
ASSUME((void *) pkt == (void *) vb);
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-19 22:00:02 +00:00
|
|
|
struct oid *oid = &vb->name;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2023-08-08 19:51:38 +00:00
|
|
|
/*
|
|
|
|
* snmp_bgp_state() check only prefix. To be sure on OID equivalence we need to
|
2022-11-15 15:29:03 +00:00
|
|
|
* compare the oid->n_subid length. All BGP static fields have same n_subid.
|
|
|
|
*/
|
2023-07-26 12:02:23 +00:00
|
|
|
if (oid_state_compare(oid, state) < 0 || state == BGP_INTERNAL_END)
|
2022-11-19 22:00:02 +00:00
|
|
|
{
|
|
|
|
vb->type = AGENTX_NO_SUCH_OBJECT;
|
2023-10-18 11:30:14 +00:00
|
|
|
return pkt + snmp_varbind_header_size(vb);
|
2023-07-26 12:02:23 +00:00
|
|
|
}
|
|
|
|
else if (oid_state_compare(oid, state) > 0)
|
|
|
|
{
|
|
|
|
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
2023-10-18 11:30:14 +00:00
|
|
|
return pkt + snmp_varbind_header_size(vb);
|
2022-11-19 22:00:02 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case BGP_INTERNAL_VERSION:
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = snmp_varbind_nstr(vb, size, BGP4_VERSIONS, 1);
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
case BGP_INTERNAL_LOCAL_AS:
|
2023-10-11 08:44:18 +00:00
|
|
|
pkt = snmp_varbind_int(vb, size, p->bgp_local_as);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BGP_INTERNAL_IDENTIFIER:
|
|
|
|
// TODO make a check
|
|
|
|
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(p->bgp_local_id));
|
2022-11-15 15:29:03 +00:00
|
|
|
break;
|
2022-11-19 22:00:02 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
default:
|
2022-11-19 22:00:02 +00:00
|
|
|
vb->type = AGENTX_NO_SUCH_OBJECT;
|
2023-10-18 11:30:14 +00:00
|
|
|
pkt += snmp_varbind_header_size(vb);
|
2023-07-26 12:02:23 +00:00
|
|
|
break;
|
2022-11-15 15:29:03 +00:00
|
|
|
}
|
2022-11-05 15:29:00 +00:00
|
|
|
|
2022-11-15 15:29:03 +00:00
|
|
|
return pkt;
|
|
|
|
}
|
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
void
|
|
|
|
snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
|
2023-09-11 11:06:20 +00:00
|
|
|
struct snmp_pdu *c)
|
2022-11-15 15:29:03 +00:00
|
|
|
{
|
2022-11-19 22:00:02 +00:00
|
|
|
u8 state = snmp_bgp_state(&vb->name);
|
2022-11-15 15:29:03 +00:00
|
|
|
|
2023-07-26 12:02:23 +00:00
|
|
|
byte *pkt;
|
2023-10-11 08:44:18 +00:00
|
|
|
if (is_static(state))
|
2023-07-26 12:02:23 +00:00
|
|
|
{
|
2023-10-25 14:23:39 +00:00
|
|
|
pkt = bgp_fill_static(p, vb, c->buffer, c->size, 0, c->byte_ord, state);
|
2023-07-26 12:02:23 +00:00
|
|
|
ADVANCE(c->buffer, c->size, pkt - c->buffer);
|
|
|
|
return;
|
|
|
|
}
|
2022-11-15 15:29:03 +00:00
|
|
|
|
2023-10-11 08:44:18 +00:00
|
|
|
if (is_dynamic(state))
|
2022-11-15 15:29:03 +00:00
|
|
|
{
|
2023-07-26 12:02:23 +00:00
|
|
|
pkt = bgp_fill_dynamic(p, vb, c, state);
|
|
|
|
ADVANCE(c->buffer, c->size, pkt - c->buffer);
|
|
|
|
return;
|
2022-11-19 22:00:02 +00:00
|
|
|
}
|
2023-10-11 08:44:18 +00:00
|
|
|
|
|
|
|
vb->type = AGENTX_NO_SUCH_OBJECT; // TODO
|
|
|
|
ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb));
|
2022-08-02 14:04:25 +00:00
|
|
|
}
|
2023-07-26 12:02:23 +00:00
|
|
|
|
2023-10-19 14:27:04 +00:00
|
|
|
#if 0
|
|
|
|
int
|
|
|
|
snmp_bgp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, void *tr, struct oid *oid, uint pkt_size)
|
|
|
|
{
|
|
|
|
// TODO: check the type of varbind vb and it's value correctness, don't overflow the pkt_size
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|