0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-18 06:51:54 +00:00

SNMP: BGP4-MIB add LocalIdentifier

This commit is contained in:
Vojtech Vilimek 2023-10-11 10:44:18 +02:00
parent 2211644ed3
commit 778906d168
6 changed files with 124 additions and 76 deletions

View File

@ -23,7 +23,7 @@ static const char * const debug_bgp_states[] UNUSED = {
[BGP_INTERNAL_LOCAL_AS] = "BGP_INTERNAL_LOCAL_AS", [BGP_INTERNAL_LOCAL_AS] = "BGP_INTERNAL_LOCAL_AS",
[BGP_INTERNAL_PEER_TABLE] = "BGP_INTERNAL_PEER_TABLE", [BGP_INTERNAL_PEER_TABLE] = "BGP_INTERNAL_PEER_TABLE",
[BGP_INTERNAL_PEER_ENTRY] = "BGP_INTERNAL_PEER_ENTRY", [BGP_INTERNAL_PEER_ENTRY] = "BGP_INTERNAL_PEER_ENTRY",
[BGP_INTERNAL_IDENTIFIER] = "BGP_INTERNAL_IDENTIFIER", [BGP_INTERNAL_PEER_IDENTIFIER] = "BGP_INTERNAL_PEER_IDENTIFIER",
[BGP_INTERNAL_STATE] = "BGP_INTERNAL_STATE", [BGP_INTERNAL_STATE] = "BGP_INTERNAL_STATE",
[BGP_INTERNAL_ADMIN_STATUS] = "BGP_INTERNAL_ADMIN_STATUS", [BGP_INTERNAL_ADMIN_STATUS] = "BGP_INTERNAL_ADMIN_STATUS",
[BGP_INTERNAL_NEGOTIATED_VERSION] = "BGP_INTERNAL_NEGOTIATED_VERSION", [BGP_INTERNAL_NEGOTIATED_VERSION] = "BGP_INTERNAL_NEGOTIATED_VERSION",
@ -47,6 +47,8 @@ static const char * const debug_bgp_states[] UNUSED = {
[BGP_INTERNAL_ORIGINATION_INTERVAL] = "BGP_INTERNAL_ORIGINATION_INTERVAL", [BGP_INTERNAL_ORIGINATION_INTERVAL] = "BGP_INTERNAL_ORIGINATION_INTERVAL",
[BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT] = "BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT", [BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT] = "BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT",
[BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME] = "BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME", [BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME] = "BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME",
[BGP_INTERNAL_PEER_TABLE_END] = "BGP_INTERNAL_PEER_TABLE_END",
[BGP_INTERNAL_IDENTIFIER] = "BGP_INTERNAL_IDENTIFIER",
[BGP_INTERNAL_END] = "BGP_INTERNAL_END", [BGP_INTERNAL_END] = "BGP_INTERNAL_END",
[BGP_INTERNAL_NO_VALUE] = "BGP_INTERNAL_NO_VALUE", [BGP_INTERNAL_NO_VALUE] = "BGP_INTERNAL_NO_VALUE",
}; };
@ -187,6 +189,7 @@ snmp_bgp_register(struct snmp_proto *p)
snmp_register(p, oid, 1, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT); snmp_register(p, oid, 1, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT);
} }
#if 0
u32 bgp_peer_entry[] = { 1, 15, 3, 1, 1 }; u32 bgp_peer_entry[] = { 1, 15, 3, 1, 1 };
u32 bound = 24; u32 bound = 24;
HASH_WALK(p->bgp_hash, next, peer) HASH_WALK(p->bgp_hash, next, peer)
@ -202,7 +205,7 @@ snmp_bgp_register(struct snmp_proto *p)
STORE_U8(oid->n_subid, 9); STORE_U8(oid->n_subid, 9);
STORE_U8(oid->prefix, SNMP_MGMT); STORE_U8(oid->prefix, SNMP_MGMT);
for (uint i = 0; i < sizeof(bgp_peer_entry)/sizeof(bgp_peer_entry[0]); i++) for (uint i = 0; i < ARRAY_SIZE(bgp_peer_entry); i++)
STORE_U32(oid->ids[i], bgp_peer_entry[i]); STORE_U32(oid->ids[i], bgp_peer_entry[i]);
ip4_to_oid(oid, ipa_to_ip4(bgp->remote_ip)); ip4_to_oid(oid, ipa_to_ip4(bgp->remote_ip));
@ -214,6 +217,7 @@ snmp_bgp_register(struct snmp_proto *p)
p->register_to_ack++; p->register_to_ack++;
} }
HASH_WALK_END; HASH_WALK_END;
#endif
} }
static int static int
@ -226,7 +230,7 @@ static u8
bgp_get_candidate(u32 field) bgp_get_candidate(u32 field)
{ {
const u8 translation_table[] = { const u8 translation_table[] = {
[SNMP_BGP_IDENTIFIER] = BGP_INTERNAL_IDENTIFIER, [SNMP_BGP_PEER_IDENTIFIER] = BGP_INTERNAL_PEER_IDENTIFIER,
[SNMP_BGP_STATE] = BGP_INTERNAL_STATE, [SNMP_BGP_STATE] = BGP_INTERNAL_STATE,
[SNMP_BGP_ADMIN_STATUS] = BGP_INTERNAL_ADMIN_STATUS, [SNMP_BGP_ADMIN_STATUS] = BGP_INTERNAL_ADMIN_STATUS,
[SNMP_BGP_NEGOTIATED_VERSION] = BGP_INTERNAL_NEGOTIATED_VERSION, [SNMP_BGP_NEGOTIATED_VERSION] = BGP_INTERNAL_NEGOTIATED_VERSION,
@ -259,9 +263,9 @@ bgp_get_candidate(u32 field)
if (field > 0 && field <= sizeof(translation_table) / sizeof(translation_table[0]) - 1) if (field > 0 && field <= sizeof(translation_table) / sizeof(translation_table[0]) - 1)
return translation_table[field]; return translation_table[field];
if (field == 0) if (field == 0)
return BGP_INTERNAL_INVALID; return BGP_INTERNAL_PEER_ENTRY;
else else
return BGP_INTERNAL_END; return BGP_INTERNAL_PEER_TABLE_END;
} }
static inline struct ip4_addr static inline struct ip4_addr
@ -415,7 +419,9 @@ snmp_bgp_state(const struct oid *oid)
/* We use candidate to avoid overriding more specific state */ /* We use candidate to avoid overriding more specific state */
candidate = BGP_INTERNAL_PEER_TABLE; candidate = BGP_INTERNAL_PEER_TABLE;
break; break;
case SNMP_BGP_IDENTIFIER:
state = BGP_INTERNAL_IDENTIFIER;
break;
default: /* test fails */ default: /* test fails */
/* We force state invalidation */ /* We force state invalidation */
@ -444,16 +450,25 @@ snmp_bgp_state(const struct oid *oid)
static inline int static inline int
is_dynamic(u8 state) is_dynamic(u8 state)
{ {
return (state >= BGP_INTERNAL_IDENTIFIER && return (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME); state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME);
} }
static inline int
is_static(u8 state)
{
return (state == BGP_INTERNAL_VERSION ||
state == BGP_INTERNAL_LOCAL_AS ||
state == BGP_INTERNAL_IDENTIFIER);
}
static inline int static inline int
snmp_bgp_has_value(u8 state) snmp_bgp_has_value(u8 state)
{ {
if (state <= BGP_INTERNAL_BGP || if (state <= BGP_INTERNAL_BGP ||
state == BGP_INTERNAL_PEER_TABLE || state == BGP_INTERNAL_PEER_TABLE ||
state == BGP_INTERNAL_PEER_ENTRY || state == BGP_INTERNAL_PEER_ENTRY ||
state == BGP_INTERNAL_PEER_TABLE_END ||
state >= BGP_INTERNAL_END) state >= BGP_INTERNAL_END)
return 0; return 0;
else else
@ -474,6 +489,7 @@ snmp_bgp_get_valid(u8 state)
state == BGP_INTERNAL_BGP || state == BGP_INTERNAL_BGP ||
state == BGP_INTERNAL_PEER_TABLE || state == BGP_INTERNAL_PEER_TABLE ||
state == BGP_INTERNAL_PEER_ENTRY || state == BGP_INTERNAL_PEER_ENTRY ||
state == BGP_INTERNAL_PEER_TABLE_END ||
state >= BGP_INTERNAL_END) state >= BGP_INTERNAL_END)
return 0; return 0;
else else
@ -495,9 +511,13 @@ snmp_bgp_next_state(u8 state)
case BGP_INTERNAL_LOCAL_AS: case BGP_INTERNAL_LOCAL_AS:
case BGP_INTERNAL_PEER_TABLE: case BGP_INTERNAL_PEER_TABLE:
case BGP_INTERNAL_PEER_ENTRY: case BGP_INTERNAL_PEER_ENTRY:
return BGP_INTERNAL_IDENTIFIER; return BGP_INTERNAL_PEER_IDENTIFIER;
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME: case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
case BGP_INTERNAL_PEER_TABLE_END:
return BGP_INTERNAL_IDENTIFIER;
case BGP_INTERNAL_IDENTIFIER:
case BGP_INTERNAL_END: case BGP_INTERNAL_END:
return BGP_INTERNAL_END; return BGP_INTERNAL_END;
@ -531,10 +551,11 @@ static int
oid_state_compare(const struct oid *oid, u8 state) oid_state_compare(const struct oid *oid, u8 state)
{ {
ASSUME(oid != NULL); ASSUME(oid != NULL);
if (state >= BGP_INTERNAL_IDENTIFIER && if (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME) state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME)
return (oid->n_subid > 9) - (oid->n_subid < 9); return (oid->n_subid > 9) - (oid->n_subid < 9);
if (state >= BGP_INTERNAL_VERSION && state <= BGP_INTERNAL_PEER_TABLE) if ((state >= BGP_INTERNAL_VERSION && state <= BGP_INTERNAL_PEER_TABLE) ||
(state == BGP_INTERNAL_IDENTIFIER))
return (oid->n_subid > 3) - (oid->n_subid < 3); return (oid->n_subid > 3) - (oid->n_subid < 3);
if (state == BGP_INTERNAL_PEER_ENTRY) if (state == BGP_INTERNAL_PEER_ENTRY)
return (oid->n_subid > 4) - (oid->n_subid < 4); return (oid->n_subid > 4) - (oid->n_subid < 4);
@ -555,7 +576,7 @@ update_bgp_oid(struct oid *oid, u8 state)
/* No need to reallocate anything if the OID has same lin. state */ /* No need to reallocate anything if the OID has same lin. state */
if (snmp_bgp_state(oid) == state) if (snmp_bgp_state(oid) == state)
{ {
if (state >= BGP_INTERNAL_IDENTIFIER && if (state >= BGP_INTERNAL_PEER_IDENTIFIER &&
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME && state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME &&
oid->n_subid == 9) oid->n_subid == 9)
return oid; return oid;
@ -597,7 +618,7 @@ update_bgp_oid(struct oid *oid, u8 state)
oid->ids[2] = SNMP_BGP_LOCAL_AS; oid->ids[2] = SNMP_BGP_LOCAL_AS;
break; break;
case BGP_INTERNAL_IDENTIFIER: case BGP_INTERNAL_PEER_IDENTIFIER:
if (oid->n_subid != 9) if (oid->n_subid != 9)
{ {
oid = mb_realloc(oid, snmp_oid_sizeof(9)); oid = mb_realloc(oid, snmp_oid_sizeof(9));
@ -615,7 +636,7 @@ update_bgp_oid(struct oid *oid, u8 state)
oid->ids[2] = SNMP_BGP_PEER_TABLE; oid->ids[2] = SNMP_BGP_PEER_TABLE;
oid->ids[3] = SNMP_BGP_PEER_ENTRY; oid->ids[3] = SNMP_BGP_PEER_ENTRY;
oid->ids[4] = SNMP_BGP_IDENTIFIER; oid->ids[4] = SNMP_BGP_PEER_IDENTIFIER;
oid->n_subid = 9; oid->n_subid = 9;
break; break;
@ -684,6 +705,14 @@ update_bgp_oid(struct oid *oid, u8 state)
SNMP_UPDATE_CASE(BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME, SNMP_BGP_IN_UPDATE_ELAPSED_TIME) SNMP_UPDATE_CASE(BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME, SNMP_BGP_IN_UPDATE_ELAPSED_TIME)
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;
default: default:
/* intentionally left blank */ /* intentionally left blank */
break; break;
@ -845,7 +874,7 @@ snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struc
snmp_log(" **searched = 0x%p *oid = 0x%p", searched, oid); snmp_log(" **searched = 0x%p *oid = 0x%p", searched, oid);
snmp_oid_dump(*searched); snmp_oid_dump(*searched);
snmp_oid_dump(oid); snmp_oid_dump(oid);
u8 end_state = snmp_bgp_state(o_end); u8 end_state = MIN(snmp_bgp_state(o_end), BGP_INTERNAL_PEER_TABLE_END);
snmp_log("before assumption %s [%u] < %u INTERNAL_END", debug_bgp_states[end_state], end_state, BGP_INTERNAL_END); snmp_log("before assumption %s [%u] < %u INTERNAL_END", debug_bgp_states[end_state], end_state, BGP_INTERNAL_END);
ASSUME(end_state <= BGP_INTERNAL_END); ASSUME(end_state <= BGP_INTERNAL_END);
@ -864,29 +893,28 @@ snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struc
snmp_log("loop"); snmp_log("loop");
next_state = snmp_bgp_next_state(next_state); next_state = snmp_bgp_next_state(next_state);
if (next_state == BGP_INTERNAL_END) if (next_state == BGP_INTERNAL_IDENTIFIER)
break; break;
oid = update_bgp_oid(oid, next_state); oid = update_bgp_oid(oid, next_state);
/* In case of search for next bgp state, we want to start from beginning. */ /* In case of search for next bgp state, we want to start from beginning. */
oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0; oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0;
} }
if (next_state < BGP_INTERNAL_END && next_state <= end_state) if (next_state < BGP_INTERNAL_PEER_TABLE_END && next_state <= end_state)
{ {
*searched = oid; *searched = oid;
return SNMP_SEARCH_OK; return SNMP_SEARCH_OK;
} }
mb_free(oid);
*searched = NULL;
return SNMP_SEARCH_END_OF_VIEW; return SNMP_SEARCH_END_OF_VIEW;
} }
enum snmp_search_res enum snmp_search_res
snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid) snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid)
{ {
enum snmp_search_res r = SNMP_SEARCH_END_OF_VIEW;
u8 bgp_state = snmp_bgp_state(*searched); u8 bgp_state = snmp_bgp_state(*searched);
struct oid *oid = *searched; u8 state;
snmp_log("snmp_bgp_search2() with state %s [%d]", debug_bgp_states[bgp_state], bgp_state); snmp_log("snmp_bgp_search2() with state %s [%d]", debug_bgp_states[bgp_state], bgp_state);
if (bgp_state == BGP_INTERNAL_END) if (bgp_state == BGP_INTERNAL_END)
@ -894,47 +922,49 @@ snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *
return SNMP_SEARCH_NO_OBJECT; return SNMP_SEARCH_NO_OBJECT;
} }
/* TODO remove todo below, then remove this code */ if (is_static(bgp_state) && (*searched)->include)
if (is_dynamic(bgp_state))
{ {
snmp_log("returning oid with dynamic state");
return snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
}
/* TODO snmp_bgp_has_value is false only for state which are not dynamic */
if (!snmp_bgp_has_value(bgp_state) || !oid->include)
{
bgp_state = snmp_bgp_next_state(bgp_state);
snmp_log("altering searched oid with next state %s [%d]", debug_bgp_states[bgp_state], bgp_state);
snmp_oid_dump(*searched);
snmp_log("after oid update:");
snmp_oid_dump(*searched);
/*
* We zero the ip address section of the oid if we go from non-dynamic state
* to dynamic one.
*/
for (int i = 5; i < MIN(9, oid->n_subid); i++)
oid->ids[i] = 0;
}
if (is_dynamic(bgp_state))
{
snmp_log("returning oid with dynamic state 2");
return snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
}
oid = *searched = update_bgp_oid(*searched, bgp_state);
if (oid->n_subid == 3 && oid->ids[2] >= SNMP_BGP_VERSION &&
oid->ids[2] <= SNMP_BGP_LOCAL_AS && bgp_state != BGP_INTERNAL_END)
{
snmp_log("oid matches static state");
oid->include = 0;
return SNMP_SEARCH_OK; return SNMP_SEARCH_OK;
} }
snmp_log("reached unguarded code, returning END_OF_VIEW"); state = snmp_bgp_next_state(bgp_state);
if (is_static(state) && !is_dynamic(bgp_state))
{
*searched = update_bgp_oid(*searched, state);
return SNMP_SEARCH_OK;
}
if (is_dynamic(state) && !is_dynamic(bgp_state))
{
snmp_log("searching a dynamic successor of static 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;
}
if (is_dynamic(bgp_state))
{
snmp_log("searching the dynamic states (peers)");
r = snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
if (r != SNMP_SEARCH_END_OF_VIEW)
return r;
}
state = snmp_bgp_next_state(bgp_state);
if (state <= BGP_INTERNAL_IDENTIFIER)
{
snmp_log("returning the local identifier");
*searched = update_bgp_oid(*searched, state);
return SNMP_SEARCH_OK;
}
// TODO add route table
/* end not found */
snmp_log("reached unguarded code, returning END_OF_VIEW");
return SNMP_SEARCH_END_OF_VIEW; return SNMP_SEARCH_END_OF_VIEW;
} }
@ -1035,7 +1065,7 @@ bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
char last_error[2] = SNMP_BGP_LAST_ERROR(bgp_proto); char last_error[2] = SNMP_BGP_LAST_ERROR(bgp_proto);
switch (state) switch (state)
{ {
case BGP_INTERNAL_IDENTIFIER: case BGP_INTERNAL_PEER_IDENTIFIER:
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED) if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
pkt = snmp_varbind_ip4(vb, size, ip4_from_u32(bgp_proto->remote_id)); pkt = snmp_varbind_ip4(vb, size, ip4_from_u32(bgp_proto->remote_id));
else else
@ -1194,7 +1224,6 @@ bgp_fill_static(struct snmp_proto *p, struct agentx_varbind *vb, byte *pkt, uint
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state) UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
{ {
snmp_log("snmp bgp_fill_static ()\n"); snmp_log("snmp bgp_fill_static ()\n");
byte *temp = pkt;
snmp_log("bgp_fill_static: vb->type %u, ptk %02x", vb->type, *((u32 *) pkt)); snmp_log("bgp_fill_static: vb->type %u, ptk %02x", vb->type, *((u32 *) pkt));
struct oid *oid = &vb->name; struct oid *oid = &vb->name;
@ -1223,22 +1252,28 @@ UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
break; break;
case BGP_INTERNAL_LOCAL_AS: case BGP_INTERNAL_LOCAL_AS:
pkt = snmp_varbind_int(vb, size, p->local_as); 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));
break; break;
case BGP_INTERNAL_BGP:
default: default:
vb->type = AGENTX_NO_SUCH_OBJECT; vb->type = AGENTX_NO_SUCH_OBJECT;
pkt = ((byte *) vb) + snmp_varbind_header_size(vb); pkt = ((byte *) vb) + snmp_varbind_header_size(vb);
break; break;
} }
#if 0
snmp_log("bgp_fill_static: type %u packet %p", vb->type, pkt); snmp_log("bgp_fill_static: type %u packet %p", vb->type, pkt);
snmp_oid_dump(oid); snmp_oid_dump(oid);
snmp_log("snmp ended with non empty pkt %u starting from %p to %p\n", pkt - snmp_log("snmp ended with non empty pkt %u starting from %p to %p\n", pkt -
temp, temp, pkt); temp, temp, pkt);
snmp_dump_packet(temp, pkt - temp); snmp_dump_packet(temp, pkt - temp);
#endif
return pkt; return pkt;
} }
@ -1249,24 +1284,21 @@ snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
u8 state = snmp_bgp_state(&vb->name); u8 state = snmp_bgp_state(&vb->name);
byte *pkt; byte *pkt;
if (!is_dynamic(state)) if (is_static(state))
{ {
pkt = bgp_fill_static(p, vb, c->buffer, c->size, c->context, c->byte_ord, state); pkt = bgp_fill_static(p, vb, c->buffer, c->size, c->context, c->byte_ord, state);
ADVANCE(c->buffer, c->size, pkt - c->buffer); ADVANCE(c->buffer, c->size, pkt - c->buffer);
return; return;
} }
if (is_dynamic(state) && snmp_bgp_has_value(state)) if (is_dynamic(state))
{ {
pkt = bgp_fill_dynamic(p, vb, c, state); pkt = bgp_fill_dynamic(p, vb, c, state);
ADVANCE(c->buffer, c->size, pkt - c->buffer); ADVANCE(c->buffer, c->size, pkt - c->buffer);
return; return;
} }
else
{ vb->type = AGENTX_NO_SUCH_OBJECT; // TODO
die("snmp_bgp_fill unreachable"); ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb));
((void) c->buffer);
return;
}
} }

View File

@ -6,7 +6,7 @@
/* peers attributes */ /* peers attributes */
enum BGP4_MIB_PEER_TABLE { enum BGP4_MIB_PEER_TABLE {
SNMP_BGP_IDENTIFIER = 1, SNMP_BGP_PEER_IDENTIFIER = 1,
SNMP_BGP_STATE = 2, SNMP_BGP_STATE = 2,
SNMP_BGP_ADMIN_STATUS = 3, /* in read-only mode */ SNMP_BGP_ADMIN_STATUS = 3, /* in read-only mode */
SNMP_BGP_NEGOTIATED_VERSION = 4, SNMP_BGP_NEGOTIATED_VERSION = 4,
@ -54,6 +54,8 @@ void snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp)
#define SNMP_BGP_LOCAL_AS 2 #define SNMP_BGP_LOCAL_AS 2
#define SNMP_BGP_PEER_TABLE 3 #define SNMP_BGP_PEER_TABLE 3
#define SNMP_BGP_PEER_ENTRY 1 #define SNMP_BGP_PEER_ENTRY 1
/* BGP4-MIB::bgpIdentifier for local identification */
#define SNMP_BGP_IDENTIFIER 4
/* BGP linearized state */ /* BGP linearized state */
enum BGP_INTERNAL_STATES { enum BGP_INTERNAL_STATES {
@ -64,7 +66,7 @@ enum BGP_INTERNAL_STATES {
BGP_INTERNAL_LOCAL_AS, BGP_INTERNAL_LOCAL_AS,
BGP_INTERNAL_PEER_TABLE, BGP_INTERNAL_PEER_TABLE,
BGP_INTERNAL_PEER_ENTRY, BGP_INTERNAL_PEER_ENTRY,
BGP_INTERNAL_IDENTIFIER, BGP_INTERNAL_PEER_IDENTIFIER,
BGP_INTERNAL_STATE, BGP_INTERNAL_STATE,
BGP_INTERNAL_ADMIN_STATUS, BGP_INTERNAL_ADMIN_STATUS,
BGP_INTERNAL_NEGOTIATED_VERSION, BGP_INTERNAL_NEGOTIATED_VERSION,
@ -89,6 +91,7 @@ enum BGP_INTERNAL_STATES {
BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT, BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT,
BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME, BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME,
BGP_INTERNAL_PEER_TABLE_END, BGP_INTERNAL_PEER_TABLE_END,
BGP_INTERNAL_IDENTIFIER, /* local identification */
BGP_INTERNAL_END, BGP_INTERNAL_END,
BGP_INTERNAL_NO_VALUE = 255, BGP_INTERNAL_NO_VALUE = 255,
} PACKED; } PACKED;

View File

@ -39,6 +39,7 @@ snmp_proto:
if (($4 < 1) || ($4 > 65535)) cf_error("Invalid port number"); if (($4 < 1) || ($4 > 65535)) cf_error("Invalid port number");
SNMP_CFG->remote_port = $4; SNMP_CFG->remote_port = $4;
} }
| snmp_proto LOCAL ID ipa ';' { SNMP_CFG->bgp_local_id = $4; }
| snmp_proto LOCAL ADDRESS ipa ';' { SNMP_CFG->local_ip = $4; } | snmp_proto LOCAL ADDRESS ipa ';' { SNMP_CFG->local_ip = $4; }
| snmp_proto REMOTE ADDRESS ipa ';' { | snmp_proto REMOTE ADDRESS ipa ';' {
if (ipa_zero($4)) cf_error("Invalid remote ip address"); if (ipa_zero($4)) cf_error("Invalid remote ip address");
@ -46,7 +47,7 @@ snmp_proto:
} }
| snmp_proto LOCAL AS expr ';' { | snmp_proto LOCAL AS expr ';' {
if ($4 < 1 || $4 > 65535) cf_error("Invalid local AS"); if ($4 < 1 || $4 > 65535) cf_error("Invalid local AS");
SNMP_CFG->local_as = $4; SNMP_CFG->bgp_local_as = $4;
} }
| snmp_proto DESCRIPTION text ';' { | snmp_proto DESCRIPTION text ';' {
if (strlen($3) > UINT32_MAX) cf_error("Description is too long"); if (strlen($3) > UINT32_MAX) cf_error("Description is too long");
@ -73,9 +74,10 @@ snmp_proto_start: proto_start SNMP
SNMP_CFG->local_ip = IPA_NONE; SNMP_CFG->local_ip = IPA_NONE;
SNMP_CFG->remote_ip = ipa_build4(127,0,0,1); SNMP_CFG->remote_ip = ipa_build4(127,0,0,1);
SNMP_CFG->bgp_local_id = IPA_NONE;
SNMP_CFG->local_port = 0; SNMP_CFG->local_port = 0;
SNMP_CFG->remote_port = 705; SNMP_CFG->remote_port = 705;
SNMP_CFG->local_as = 0; SNMP_CFG->bgp_local_as = 0;
SNMP_CFG->description = "bird"; SNMP_CFG->description = "bird";
SNMP_CFG->timeout = 15; SNMP_CFG->timeout = 15;

View File

@ -102,7 +102,10 @@ snmp_init(struct proto_config *CF)
p->remote_ip = cf->remote_ip; p->remote_ip = cf->remote_ip;
p->local_port = cf->local_port; p->local_port = cf->local_port;
p->remote_port = cf->remote_port; p->remote_port = cf->remote_port;
p->local_as = cf->local_as;
p->bgp_local_as = cf->bgp_local_as;
p->bgp_local_id = cf->bgp_local_id;
snmp_log("changing proto_snmp state to INIT"); snmp_log("changing proto_snmp state to INIT");
p->state = SNMP_INIT; p->state = SNMP_INIT;
@ -440,8 +443,11 @@ snmp_show_proto_info(struct proto *P)
cli_msg(-1006, ""); cli_msg(-1006, "");
cli_msg(-1006, " snmp status %s", snmp_state[sp->state]); cli_msg(-1006, " snmp status %s", snmp_state[sp->state]);
cli_msg(-1006, " default local as %u", sp->bgp_local_as);
cli_msg(-1006, " default local id %I4", sp->bgp_local_id);
cli_msg(-1006, ""); cli_msg(-1006, "");
cli_msg(-1006, " BGP peers"); cli_msg(-1006, " BGP peers");
struct snmp_bond *bond; struct snmp_bond *bond;
WALK_LIST(bond, c->bgp_entries) WALK_LIST(bond, c->bgp_entries)
{ {
@ -505,7 +511,7 @@ static void
snmp_postconfig(struct proto_config *CF) snmp_postconfig(struct proto_config *CF)
{ {
/* Walk the BGP protocols and cache their references. */ /* Walk the BGP protocols and cache their references. */
if (((struct snmp_config *) CF)->local_as == 0) if (((struct snmp_config *) CF)->bgp_local_as == 0)
cf_error("local as not specified"); cf_error("local as not specified");
} }

View File

@ -70,7 +70,10 @@ struct snmp_config {
ip_addr remote_ip; ip_addr remote_ip;
u16 local_port; u16 local_port;
u16 remote_port; u16 remote_port;
u32 local_as;
ip_addr bgp_local_id; /* BGP4-MIB related fields */
u32 bgp_local_as;
u8 timeout; u8 timeout;
u8 priority; u8 priority;
//struct iface *iface; //struct iface *iface;
@ -123,7 +126,9 @@ struct snmp_proto {
ip_addr remote_ip; ip_addr remote_ip;
u16 local_port; u16 local_port;
u16 remote_port; u16 remote_port;
u32 local_as;
ip_addr bgp_local_id; /* BGP4-MIB related fields */
u32 bgp_local_as;
sock *sock; sock *sock;
u8 timeout; /* timeout is part of MIB registration. It u8 timeout; /* timeout is part of MIB registration. It

View File

@ -1097,7 +1097,7 @@ void
snmp_start_subagent(struct snmp_proto *p) snmp_start_subagent(struct snmp_proto *p)
{ {
snmp_log("snmp_start_subagent() starting subagent"); snmp_log("snmp_start_subagent() starting subagent");
snmp_log("DEBUG p->local_as %u", p->local_as); snmp_log("DEBUG p->bgp_local_as %u", p->bgp_local_as);
/* blank oid means unsupported */ /* blank oid means unsupported */
struct oid *blank = snmp_oid_blank(p); struct oid *blank = snmp_oid_blank(p);