0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

SNMP: Refactor -- order + cleanup

The C source files are read from bottom up.
This commit is contained in:
Vojtech Vilimek 2024-08-15 15:52:15 +02:00
parent 35954b667f
commit f871700239
7 changed files with 1066 additions and 1314 deletions

View File

@ -67,6 +67,32 @@ snmp_bgp_reg_failed(struct snmp_proto *p, const struct agentx_response *res, str
snmp_reset(p); snmp_reset(p);
} }
/*
* snmp_bgp_fsm_state - extract BGP FSM state for SNMP BGP4-MIB
* @bgp_proto: BGP instance
*
* Return FSM state in BGP4-MIB encoding
*/
static inline uint
snmp_bgp_fsm_state(const 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 + 1;
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) + 1;
if (MIN(bgp_in->state, bgp_out->state) == BS_CLOSE)
return BS_IDLE;
return MAX(bgp_in->state, bgp_out->state) + 1;
}
/* /*
* snmp_bgp_notify_common - common functionaly for BGP4-MIB notifications * snmp_bgp_notify_common - common functionaly for BGP4-MIB notifications
* @p: SNMP protocol instance * @p: SNMP protocol instance
@ -173,31 +199,6 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_
#undef OID_N_SUBID #undef OID_N_SUBID
} }
/*
* snmp_bgp_fsm_state - extract BGP FSM state for SNMP BGP4-MIB
* @bgp_proto: BGP instance
*
* Return FSM state in BGP4-MIB encoding
*/
static inline uint
snmp_bgp_fsm_state(const 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 + 1;
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) + 1;
if (MIN(bgp_in->state, bgp_out->state) == BS_CLOSE)
return BS_IDLE;
return MAX(bgp_in->state, bgp_out->state) + 1;
}
static void static void
snmp_bgp_notify_wrapper(struct snmp_proto *p, struct bgp_proto *bgp, uint type) snmp_bgp_notify_wrapper(struct snmp_proto *p, struct bgp_proto *bgp, uint type)
{ {
@ -209,38 +210,18 @@ snmp_bgp_notify_wrapper(struct snmp_proto *p, struct bgp_proto *bgp, uint type)
snmp_bgp_notify_common(p, type, ip4, last_error, state_val); snmp_bgp_notify_common(p, type, ip4, last_error, state_val);
} }
void void UNUSED
snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp) snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp)
{ {
snmp_bgp_notify_wrapper(p, bgp, BGP4_MIB_ESTABLISHED_NOTIFICATION); snmp_bgp_notify_wrapper(p, bgp, BGP4_MIB_ESTABLISHED_NOTIFICATION);
} }
void void UNUSED
snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp) snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp)
{ {
snmp_bgp_notify_wrapper(p, bgp, BGP4_MIB_BACKWARD_TRANS_NOTIFICATION); snmp_bgp_notify_wrapper(p, bgp, BGP4_MIB_BACKWARD_TRANS_NOTIFICATION);
} }
void
snmp_bgp4_register(struct snmp_proto *p)
{
/* Register the whole BGP4-MIB::bgp root tree node */
struct snmp_registration *reg;
reg = snmp_registration_create(p, BGP4_MIB_ID);
struct oid *oid = mb_allocz(p->pool, sizeof(bgp4_mib_oid));
memcpy(oid, &bgp4_mib_oid, sizeof(bgp4_mib_oid));
reg->reg_hook_ok = NULL;
reg->reg_hook_fail = snmp_bgp_reg_failed;
/*
* We set both upper bound and index to zero, therefore only single OID
* is being registered.
*/
snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE);
}
static int static int
snmp_bgp_valid_ip4(const struct oid *o) snmp_bgp_valid_ip4(const struct oid *o)
{ {
@ -269,48 +250,6 @@ ip4_to_oid(struct oid *o, ip4_addr addr)
o->ids[8] = (tmp & 0x000000FF) >> 0; o->ids[8] = (tmp & 0x000000FF) >> 0;
} }
static void UNUSED
print_bgp_record(const struct bgp_proto *bgp_proto)
{
struct bgp_conn *conn = bgp_proto->conn;
DBG(" name: %s", cf->name);
DBG(".");
DBG(" rem. identifier: %u", bgp_proto->remote_id);
DBG(" local ip: %I", config->local_ip);
DBG(" remote ip: %I", config->remote_ip);
DBG(" local port: %u", config->local_port);
DBG(" remote port: %u", config->remote_port);
if (conn) {
DBG(" state: %u", conn->state);
DBG(" remote as: %u", conn->remote_caps->as4_number);
}
DBG(" in updates: %u", bgp_proto->stats.rx_updates);
DBG(" out updates: %u", bgp_proto->stats.tx_updates);
DBG(" in total: %u", bgp_proto->stats.rx_messages);
DBG(" out total: %u", bgp_proto->stats.tx_messages);
DBG(" fsm transitions: %u",
bgp_proto->stats.fsm_established_transitions);
DBG(" fsm total time: -- (0)"); // not supported by bird
DBG(" retry interval: %u", config->connect_retry_time);
DBG(" hold configurated: %u", config->hold_time );
DBG(" keep alive config: %u", config->keepalive_time );
DBG(" min AS origin. int.: -- (0)"); // not supported by bird
DBG(" min route advertisement: %u", 0 );
DBG(" in update elapsed time: %u", 0 );
if (!conn)
DBG(" no connection established");
DBG(" outgoinin_conn state %u", bgp_proto->outgoing_conn.state + 1);
DBG(" incoming_conn state: %u", bgp_proto->incoming_conn.state + 1);
}
static inline enum snmp_search_res static inline enum snmp_search_res
populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn
**conn, const struct bgp_stats **stats, const struct bgp_config **config) **conn, const struct bgp_stats **stats, const struct bgp_config **config)
@ -832,6 +771,27 @@ snmp_bgp4_show_info(struct snmp_proto *p)
HASH_WALK_END; HASH_WALK_END;
} }
void
snmp_bgp4_register(struct snmp_proto *p)
{
/* Register the whole BGP4-MIB::bgp root tree node */
struct snmp_registration *reg;
reg = snmp_registration_create(p, BGP4_MIB_ID);
struct oid *oid = mb_allocz(p->pool, sizeof(bgp4_mib_oid));
memcpy(oid, &bgp4_mib_oid, sizeof(bgp4_mib_oid));
reg->reg_hook_ok = NULL;
reg->reg_hook_fail = snmp_bgp_reg_failed;
/*
* We set both upper bound and index to zero, therefore only single OID
* is being registered.
*/
snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE);
}
/* /*
* snmp_bgp4_start - prepare BGP4-MIB * snmp_bgp4_start - prepare BGP4-MIB
* @p: SNMP protocol instance holding memory pool * @p: SNMP protocol instance holding memory pool

View File

@ -112,12 +112,6 @@
#include "bgp4_mib.h" #include "bgp4_mib.h"
const char agentx_master_addr[] = AGENTX_MASTER_ADDR; const char agentx_master_addr[] = AGENTX_MASTER_ADDR;
const struct oid *agentx_available_mibs[AGENTX_MIB_COUNT + 1] = { 0 };
static void snmp_start_locked(struct object_lock *lock);
static void snmp_sock_err(sock *sk, int err);
static void snmp_stop_timeout(timer *tm);
static void snmp_cleanup(struct snmp_proto *p);
static const char *snmp_state_str[] = { static const char *snmp_state_str[] = {
[SNMP_INIT] = "acquiring address lock", [SNMP_INIT] = "acquiring address lock",
@ -129,6 +123,109 @@ static const char *snmp_state_str[] = {
[SNMP_DOWN] = "protocol down", [SNMP_DOWN] = "protocol down",
}; };
/*
* Callbacks
*/
/*
* snmp_sock_err - handle errors on socket by reopenning the socket
* @sk: socket owned by SNMP protocol instance
* @err: socket error code
*/
static void
snmp_sock_err(sock *sk, int UNUSED err)
{
struct snmp_proto *p = sk->data;
if (err != 0)
TRACE(D_EVENTS, "SNMP socket error (%d)", err);
snmp_set_state(p, SNMP_DOWN);
}
/*
* snmp_ping_timeout - send a agentx-Ping-PDU
* @tm: the ping_timer holding the SNMP protocol instance.
*
* Send an agentx-Ping-PDU. This function is periodically called by ping
* timer.
*/
static void
snmp_ping_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_ping(p);
}
/*
* snmp_stop_timeout - a timeout for non-responding master agent
* @tm: the startup_timer holding the SNMP protocol instance.
*
* We are trying to empty the TX buffer of communication socket. But if it is
* not done in reasonable amount of time, the function is called by timeout
* timer. We down the whole SNMP protocol with cleanup of associated data
* structures.
*/
static void
snmp_stop_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_set_state(p, SNMP_DOWN);
}
/*
* snmp_connected - start AgentX session on created socket
* @sk: socket owned by SNMP protocol instance
*
* Starts the AgentX communication by sending an agentx-Open-PDU.
* This function is internal and shouldn't be used outside the SNMP module.
*/
void
snmp_connected(sock *sk)
{
struct snmp_proto *p = sk->data;
snmp_set_state(p, SNMP_OPEN);
}
/*
* snmp_start_locked - open the socket on locked address
* @lock: object lock guarding the communication mean (address, ...)
*
* This function is called when the object lock is acquired. Main goal is to set
* socket parameters and try to open configured socket. Function
* snmp_connected() handles next stage of SNMP protocol start. When the socket
* coundn't be opened, a new try is scheduled after a small delay.
*/
static void
snmp_start_locked(struct object_lock *lock)
{
struct snmp_proto *p = lock->data;
if (p->startup_delay)
{
ASSERT(p->startup_timer);
p->startup_timer->hook = snmp_startup_timeout;
tm_start(p->startup_timer, p->startup_delay);
}
else
snmp_set_state(p, SNMP_LOCKED);
}
/*
* snmp_startup_timeout - start the initiliazed SNMP protocol
* @tm: the startup_timer holding the SNMP protocol instance.
*
* When the timer rings, the function snmp_startup() is invoked.
* This function is internal and shouldn't be used outside the SNMP module.
* Used when we delaying the start procedure, or we want to retry opening
* the communication socket.
*/
void
snmp_startup_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_set_state(p, SNMP_LOCKED);
}
/* /*
* snmp_rx_skip - skip all received data * snmp_rx_skip - skip all received data
* @sk: communication socket * @sk: communication socket
@ -158,6 +255,51 @@ snmp_tx_skip(sock *sk)
snmp_set_state(p, SNMP_STOP); snmp_set_state(p, SNMP_STOP);
} }
/*
* snmp_cleanup - free all resources allocated by SNMP protocol
* @p: SNMP protocol instance
*
* This function forcefully stops and cleans all resources and memory acqiured
* by given SNMP protocol instance, such as timers, lists, hash tables etc.
*/
static inline void
snmp_cleanup(struct snmp_proto *p)
{
/* Function tm_stop() is called inside rfree() */
rfree(p->startup_timer);
p->startup_timer = NULL;
rfree(p->ping_timer);
p->ping_timer = NULL;
rfree(p->sock);
p->sock = NULL;
rfree(p->lock);
p->lock = NULL;
struct snmp_registration *r, *r2;
WALK_LIST_DELSAFE(r, r2, p->registration_queue)
{
rem_node(&r->n);
mb_free(r);
r = NULL;
}
HASH_FREE(p->bgp_hash);
rfree(p->lp);
p->lp = NULL;
/* bgp_trie is allocated exclusively from linpool lp */
p->bgp_trie = NULL;
struct mib_walk_state *walk = tmp_alloc(sizeof(struct mib_walk_state));
mib_tree_walk_init(walk, p->mib_tree);
(void) mib_tree_delete(p->mib_tree, walk);
p->mib_tree = NULL;
p->state = SNMP_DOWN;
}
/* /*
* snmp_set_state - change state with associated actions * snmp_set_state - change state with associated actions
* @p: SNMP protocol instance * @p: SNMP protocol instance
@ -303,84 +445,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
} }
} }
/*
* snmp_init - preinitialize SNMP instance
* @CF: SNMP configuration generic handle
*
* Returns a generic handle pointing to preinitialized SNMP procotol
* instance.
*/
static struct proto *
snmp_init(struct proto_config *CF)
{
struct proto *P = proto_new(CF);
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
p->rl_gen = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
p->state = SNMP_DOWN;
return P;
}
/*
* snmp_cleanup - free all resources allocated by SNMP protocol
* @p: SNMP protocol instance
*
* This function forcefully stops and cleans all resources and memory acqiured
* by given SNMP protocol instance, such as timers, lists, hash tables etc.
*/
static inline void
snmp_cleanup(struct snmp_proto *p)
{
/* Function tm_stop() is called inside rfree() */
rfree(p->startup_timer);
p->startup_timer = NULL;
rfree(p->ping_timer);
p->ping_timer = NULL;
rfree(p->sock);
p->sock = NULL;
rfree(p->lock);
p->lock = NULL;
struct snmp_registration *r, *r2;
WALK_LIST_DELSAFE(r, r2, p->registration_queue)
{
rem_node(&r->n);
mb_free(r);
r = NULL;
}
HASH_FREE(p->bgp_hash);
rfree(p->lp);
p->lp = NULL;
/* bgp_trie is allocated exclusively from linpool lp */
p->bgp_trie = NULL;
struct mib_walk_state *walk = tmp_alloc(sizeof(struct mib_walk_state));
mib_tree_walk_init(walk, p->mib_tree);
(void) mib_tree_delete(p->mib_tree, walk);
p->mib_tree = NULL;
p->state = SNMP_DOWN;
}
/*
* snmp_connected - start AgentX session on created socket
* @sk: socket owned by SNMP protocol instance
*
* Starts the AgentX communication by sending an agentx-Open-PDU.
* This function is internal and shouldn't be used outside the SNMP module.
*/
void
snmp_connected(sock *sk)
{
struct snmp_proto *p = sk->data;
snmp_set_state(p, SNMP_OPEN);
}
/* /*
* snmp_reset - reset AgentX session * snmp_reset - reset AgentX session
* @p: SNMP protocol instance * @p: SNMP protocol instance
@ -409,129 +473,31 @@ snmp_up(struct snmp_proto *p)
} }
/* /*
* snmp_sock_err - handle errors on socket by reopenning the socket * snmp_shutdown - Forcefully stop the SNMP protocol instance
* @sk: socket owned by SNMP protocol instance
* @err: socket error code
*/
static void
snmp_sock_err(sock *sk, int UNUSED err)
{
struct snmp_proto *p = sk->data;
if (err != 0)
TRACE(D_EVENTS, "SNMP socket error (%d)", err);
snmp_set_state(p, SNMP_DOWN);
}
/*
* snmp_start_locked - open the socket on locked address
* @lock: object lock guarding the communication mean (address, ...)
*
* This function is called when the object lock is acquired. Main goal is to set
* socket parameters and try to open configured socket. Function
* snmp_connected() handles next stage of SNMP protocol start. When the socket
* coundn't be opened, a new try is scheduled after a small delay.
*/
static void
snmp_start_locked(struct object_lock *lock)
{
struct snmp_proto *p = lock->data;
if (p->startup_delay)
{
ASSERT(p->startup_timer);
p->startup_timer->hook = snmp_startup_timeout;
tm_start(p->startup_timer, p->startup_delay);
}
else
snmp_set_state(p, SNMP_LOCKED);
}
/*
* snmp_startup_timeout - start the initiliazed SNMP protocol
* @tm: the startup_timer holding the SNMP protocol instance.
*
* When the timer rings, the function snmp_startup() is invoked.
* This function is internal and shouldn't be used outside the SNMP module.
* Used when we delaying the start procedure, or we want to retry opening
* the communication socket.
*/
void
snmp_startup_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_set_state(p, SNMP_LOCKED);
}
/*
* snmp_stop_timeout - a timeout for non-responding master agent
* @tm: the startup_timer holding the SNMP protocol instance.
*
* We are trying to empty the TX buffer of communication socket. But if it is
* not done in reasonable amount of time, the function is called by timeout
* timer. We down the whole SNMP protocol with cleanup of associated data
* structures.
*/
static void
snmp_stop_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_set_state(p, SNMP_DOWN);
}
/*
* snmp_ping_timeout - send a agentx-Ping-PDU
* @tm: the ping_timer holding the SNMP protocol instance.
*
* Send an agentx-Ping-PDU. This function is periodically called by ping
* timer.
*/
static void
snmp_ping_timeout(timer *tm)
{
struct snmp_proto *p = tm->data;
snmp_ping(p);
}
/*
* snmp_start - Initialize the SNMP protocol instance
* @P: SNMP protocol generic handle * @P: SNMP protocol generic handle
* *
* The first step in AgentX subagent startup is protocol initialition. * Simple cast-like wrapper around snmp_reset(), see more info there.
* We must prepare lists, find BGP peers and finally asynchronously start
* a AgentX subagent session.
*/ */
static int static int
snmp_start(struct proto *P) snmp_shutdown(struct proto *P)
{
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
return snmp_reset(p);
}
/*
* snmp_show_proto_info - print basic information about SNMP protocol instance
* @P: SNMP protocol generic handle
*/
static void
snmp_show_proto_info(struct proto *P)
{ {
struct snmp_proto *p = (void *) P; struct snmp_proto *p = (void *) P;
struct snmp_config *cf = (struct snmp_config *) P->cf;
p->local_ip = cf->local_ip; cli_msg(-1006, " SNMP state: %s", snmp_state_str[p->state]);
p->remote_ip = cf->remote_ip; cli_msg(-1006, " MIBs");
p->local_port = cf->local_port;
p->remote_port = cf->remote_port;
p->bgp_local_as = cf->bgp_local_as;
p->bgp_local_id = cf->bgp_local_id;
p->timeout = cf->timeout;
p->startup_delay = cf->startup_delay;
p->verbose = cf->verbose;
p->pool = p->p.pool; snmp_bgp4_show_info(p);
p->lp = lp_new(p->pool);
p->bgp_trie = f_new_trie(p->lp, 0);
p->mib_tree = mb_alloc(p->pool, sizeof(struct mib_tree));
p->startup_timer = tm_new_init(p->pool, snmp_startup_timeout, p, 0, 0);
p->ping_timer = tm_new_init(p->pool, snmp_ping_timeout, p, p->timeout, 0);
init_list(&p->registration_queue);
/* We create copy of bonds to BGP protocols. */
HASH_INIT(p->bgp_hash, p->pool, 10);
mib_tree_init(p->pool, p->mib_tree);
snmp_bgp4_start(p, 1);
return snmp_set_state(p, SNMP_INIT);
} }
/* /*
@ -614,18 +580,65 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
} }
/* /*
* snmp_show_proto_info - print basic information about SNMP protocol instance * snmp_start - Initialize the SNMP protocol instance
* @P: SNMP protocol generic handle * @P: SNMP protocol generic handle
*
* The first step in AgentX subagent startup is protocol initialition.
* We must prepare lists, find BGP peers and finally asynchronously start
* a AgentX subagent session.
*/ */
static void static int
snmp_show_proto_info(struct proto *P) snmp_start(struct proto *P)
{ {
struct snmp_proto *p = (void *) P; struct snmp_proto *p = (void *) P;
struct snmp_config *cf = (struct snmp_config *) P->cf;
cli_msg(-1006, " SNMP state: %s", snmp_state_str[p->state]); p->local_ip = cf->local_ip;
cli_msg(-1006, " MIBs"); p->remote_ip = cf->remote_ip;
p->local_port = cf->local_port;
p->remote_port = cf->remote_port;
p->bgp_local_as = cf->bgp_local_as;
p->bgp_local_id = cf->bgp_local_id;
p->timeout = cf->timeout;
p->startup_delay = cf->startup_delay;
p->verbose = cf->verbose;
snmp_bgp4_show_info(p); p->pool = p->p.pool;
p->lp = lp_new(p->pool);
p->bgp_trie = f_new_trie(p->lp, 0);
p->mib_tree = mb_alloc(p->pool, sizeof(struct mib_tree));
p->startup_timer = tm_new_init(p->pool, snmp_startup_timeout, p, 0, 0);
p->ping_timer = tm_new_init(p->pool, snmp_ping_timeout, p, p->timeout, 0);
init_list(&p->registration_queue);
/* We create copy of bonds to BGP protocols. */
HASH_INIT(p->bgp_hash, p->pool, 10);
mib_tree_init(p->pool, p->mib_tree);
snmp_bgp4_start(p, 1);
return snmp_set_state(p, SNMP_INIT);
}
/*
* snmp_init - preinitialize SNMP instance
* @CF: SNMP configuration generic handle
*
* Returns a generic handle pointing to preinitialized SNMP procotol
* instance.
*/
static struct proto *
snmp_init(struct proto_config *CF)
{
struct proto *P = proto_new(CF);
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
p->rl_gen = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
p->state = SNMP_DOWN;
return P;
} }
/* /*
@ -642,19 +655,6 @@ snmp_postconfig(struct proto_config *CF)
cf_error("local as not specified"); cf_error("local as not specified");
} }
/*
* snmp_shutdown - Forcefully stop the SNMP protocol instance
* @P: SNMP protocol generic handle
*
* Simple cast-like wrapper around snmp_reset(), see more info there.
*/
static int
snmp_shutdown(struct proto *P)
{
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
return snmp_reset(p);
}
/* /*
* Protocol infrastructure * Protocol infrastructure
@ -670,8 +670,8 @@ struct protocol proto_snmp = {
.init = snmp_init, .init = snmp_init,
.start = snmp_start, .start = snmp_start,
.reconfigure = snmp_reconfigure, .reconfigure = snmp_reconfigure,
.shutdown = snmp_shutdown,
.show_proto_info = snmp_show_proto_info, .show_proto_info = snmp_show_proto_info,
.shutdown = snmp_shutdown,
}; };
void void

View File

@ -53,6 +53,15 @@ enum snmp_transport_type {
SNMP_TRANS_TCP, SNMP_TRANS_TCP,
}; };
#define SNMP_BGP_P_REGISTERING 0x01
#define SNMP_BGP_P_REGISTERED 0x02
struct snmp_bgp_peer {
const struct bgp_proto *bgp_proto;
ip4_addr peer_ip; /* used as hash key */
struct snmp_bgp_peer *next;
};
struct snmp_config { struct snmp_config {
struct proto_config cf; struct proto_config cf;
enum snmp_transport_type trans_type; enum snmp_transport_type trans_type;
@ -79,21 +88,6 @@ struct snmp_config {
int verbose; int verbose;
}; };
#define SNMP_BGP_P_REGISTERING 0x01
#define SNMP_BGP_P_REGISTERED 0x02
struct snmp_bgp_peer {
const struct bgp_proto *bgp_proto;
ip4_addr peer_ip; /* used as hash key */
struct snmp_bgp_peer *next;
};
struct snmp_registered_oid {
node n;
struct oid *oid;
};
struct snmp_proto { struct snmp_proto {
struct proto p; struct proto p;
struct object_lock *lock; struct object_lock *lock;
@ -165,7 +159,6 @@ void snmp_connected(sock *sk);
void snmp_startup_timeout(timer *tm); void snmp_startup_timeout(timer *tm);
void snmp_reconnect(timer *tm); void snmp_reconnect(timer *tm);
int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state); int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state);
int snmp_reset(struct snmp_proto *p); int snmp_reset(struct snmp_proto *p);
void snmp_up(struct snmp_proto *p); void snmp_up(struct snmp_proto *p);

View File

@ -36,12 +36,6 @@ snmp_session(const struct snmp_proto *p, struct agentx_header *h)
STORE_U32(h->packet_id, p->packet_id); STORE_U32(h->packet_id, p->packet_id);
} }
inline int
snmp_has_context(const struct agentx_header *h)
{
return h->flags & AGENTX_NON_DEFAULT_CONTEXT;
}
inline void * inline void *
snmp_varbind_data(const struct agentx_varbind *vb) snmp_varbind_data(const struct agentx_varbind *vb)
{ {
@ -49,45 +43,6 @@ snmp_varbind_data(const struct agentx_varbind *vb)
return (void *) &vb->name + name_size; return (void *) &vb->name + name_size;
} }
struct oid *
snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len)
{
struct oid *oid = &(*vb)->name;
if (oid->n_subid >= len)
{
c->size += (oid->n_subid - len) * sizeof(u32);
oid->n_subid = len;
return oid;
}
/* We need more space */
ASSUME(len >= oid->n_subid);
uint diff_size = (len - oid->n_subid) * sizeof(u32);
if (snmp_tbuf_reserve(c, diff_size))
oid = &(*vb)->name;
ASSERT(c->size >= diff_size);
c->size -= diff_size;
oid->n_subid = len;
return &(*vb)->name;
}
void
snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb)
{
ASSUME(vb != NULL && *vb != NULL);
uint hdr_size = snmp_varbind_header_size(&(*vb)->name);
(void) snmp_tbuf_reserve(c, hdr_size);
ASSERT(c->size >= hdr_size);
byte *buffer = c->buffer;
ADVANCE(c->buffer, c->size, hdr_size);
memcpy(buffer, *vb, hdr_size);
*vb = (struct agentx_varbind *) buffer;
}
/** /**
* snmp_is_oid_empty - check if oid is null-valued * snmp_is_oid_empty - check if oid is null-valued
* @oid: object identifier to check * @oid: object identifier to check
@ -128,18 +83,6 @@ snmp_oid_is_prefixable(const struct oid *oid)
return 1; return 1;
} }
/**
* snmp_pkt_len - returns size of SNMP packet payload (without header)
* @buf: packet first byte
* @pkt: first byte past packet end
*/
uint
snmp_pkt_len(const byte *start, const byte *end)
{
return (end - start) - AGENTX_HEADER_SIZE;
}
/* /*
* snmp_oid_copy - copy OID from one place to another * snmp_oid_copy - copy OID from one place to another
* @dest: destination to use * @dest: destination to use
@ -190,29 +133,6 @@ snmp_oid_to_buf(struct oid *dst, const struct oid *src)
STORE_U32(dst->ids[i], src->ids[i]); STORE_U32(dst->ids[i], src->ids[i]);
} }
/*
* snmp_oid_duplicate - duplicate an OID from memory pool
* @pool: pool to use
* @oid: OID to be duplicated
*/
struct oid *
snmp_oid_duplicate(pool *pool, const struct oid *oid)
{
struct oid *res = mb_alloc(pool, snmp_oid_size(oid));
memcpy(res, oid, snmp_oid_size(oid));
return res;
}
/**
* snmp_oid_blank - create new null oid (blank)
* @p: pool hodling snmp_proto structure
*/
struct oid *
snmp_oid_blank(struct snmp_proto *p)
{
return mb_allocz(p->p.pool, sizeof(struct oid));
}
/** /**
* snmp_str_size_from_len - return in-buffer octet string size * snmp_str_size_from_len - return in-buffer octet string size
* @len: length of C-string, returned from strlen() * @len: length of C-string, returned from strlen()
@ -278,12 +198,6 @@ snmp_varbind_header_size(const struct oid *vb_name)
return snmp_oid_size(vb_name) + OFFSETOF(struct agentx_varbind, name); return snmp_oid_size(vb_name) + OFFSETOF(struct agentx_varbind, name);
} }
/*
* Beware that for octet string, using this function may be a bit tricky due to
* the different byte orders cpu native/packet
*
*
*/
uint uint
snmp_varbind_size_unsafe(const struct agentx_varbind *vb) snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
{ {
@ -316,66 +230,6 @@ snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
} }
} }
/**
* snmp_varbind_size - get size of in-buffer VarBind
* @vb: VarBind in cpu native byte order to measure
* @limit: upper limit of bytes that can be used
*
* This functions assumes valid VarBind type.
* Return 0 for Varbinds longer than limit, Varbind's size otherwise.
*/
uint UNUSED
snmp_varbind_size(const struct agentx_varbind *vb, uint limit)
{
if (limit < sizeof(struct agentx_varbind))
return 0;
if (!snmp_test_varbind_type(vb->type))
return 0;
enum agentx_type type = vb->type;
int s = agentx_type_size(type);
uint vb_header = snmp_varbind_header_size(&vb->name);
if (limit < vb_header)
return 0;
if (s == 0)
return vb_header;
if (s > 0 && vb_header + s <= limit)
return vb_header + s;
else if (s > 0)
return 0;
uint sz;
switch (type)
{
case AGENTX_OBJECT_ID:;
struct oid *oid = snmp_varbind_data(vb);
/* snmp_oid_size works for both native and packet byte order */
sz = snmp_oid_size(oid);
if (limit < vb_header + sz)
return 0;
else
return vb_header + snmp_oid_size(oid);
case AGENTX_OCTET_STRING:
case AGENTX_IP_ADDRESS:
case AGENTX_OPAQUE:;
struct agentx_octet_str *os = snmp_varbind_data(vb);
sz = snmp_get_octet_size(os);
if (limit < vb_header + sz)
return 0;
else
return vb_header + sz;
default:
/* This should not happen */
return 0;
}
}
/** /**
* snmp_varbind_size_from_len - get size in-buffer VarBind for known OID and data * snmp_varbind_size_from_len - get size in-buffer VarBind for known OID and data
* @n_subid: number of subidentifiers of the VarBind's OID name * @n_subid: number of subidentifiers of the VarBind's OID name
@ -429,7 +283,7 @@ snmp_test_varbind_type(u16 type)
/** /**
* snmp_oid_ip4_index - check IPv4 address validity in oid * snmp_valid_ip4_index - check IPv4 address validity in oid
* @o: object identifier holding ip address * @o: object identifier holding ip address
* @start: index of first address id * @start: index of first address id
*/ */
@ -534,25 +388,6 @@ snmp_put_fbyte(byte *buf, u8 data)
return buf + 3; return buf + 3;
} }
/*
* snmp_oid_ip4_index - OID append IPv4 index
* @o: OID to use
* @start: index of IP addr's MSB
* @addr: IPv4 address to use
*
* The indices from start to (inclusive) start+3 are overwritten by @addr bytes.
*/
void
snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr)
{
u32 temp = ip4_to_u32(addr);
o->ids[start] = temp >> 24;
o->ids[start + 1] = (temp >> 16) & 0xFF;
o->ids[start + 2] = (temp >> 8) & 0xFF;
o->ids[start + 3] = temp & 0xFF;
}
/** /**
* snmp_oid_compare - find the lexicographical order relation between @left and @right * snmp_oid_compare - find the lexicographical order relation between @left and @right
* @left: left object id relation operant * @left: left object id relation operant
@ -654,8 +489,8 @@ snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib)
r->n.prev = r->n.next = NULL; r->n.prev = r->n.next = NULL;
r->session_id = p->session_id; r->session_id = p->session_id;
/* will be incremented by snmp_session() macro during packet assembly */
r->transaction_id = p->transaction_id; r->transaction_id = p->transaction_id;
/* will be incremented by snmp_session() macro during packet assembly */
r->packet_id = p->packet_id + 1; r->packet_id = p->packet_id + 1;
r->mib = mib; r->mib = mib;
@ -673,15 +508,6 @@ snmp_registration_match(struct snmp_registration *r, struct agentx_header *h)
} }
void UNUSED
snmp_dump_packet(byte UNUSED *pkt, uint size)
{
DBG("dump");
for (uint i = 0; i < size; i += 4)
DBG("pkt [%d] 0x%02x%02x%02x%02x", i, pkt[i],pkt[i+1],pkt[i+2],pkt[i+3]);
DBG("end dump");
}
/* /*
* agentx_type_size - get in packet VarBind type size * agentx_type_size - get in packet VarBind type size
* @type: VarBind type * @type: VarBind type
@ -759,18 +585,6 @@ snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr)
c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr); c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr);
} }
#if 0
inline byte *
snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len)
{
if (size < snmp_str_size_from_len(len))
return NULL;
c->sr_vb_start = AGENTX_OCTET_STRING;
return snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
}
#endif
/* /*
* snmp_varbind_nstr - fill varbind context with octet string * snmp_varbind_nstr - fill varbind context with octet string
* @vb: VarBind to use * @vb: VarBind to use
@ -894,6 +708,8 @@ snmp_oid_log(const struct oid *oid)
* be NULL OID in cases where there is no common subid. The result could be also * be NULL OID in cases where there is no common subid. The result could be also
* viewed as longest common prefix. Note that if both @left and @right are * viewed as longest common prefix. Note that if both @left and @right are
* prefixable but not prefixed the result in @out will also not be prefixed. * prefixable but not prefixed the result in @out will also not be prefixed.
*
* This function is used intensively by snmp_test.c.
*/ */
void void
snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct oid *out) snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct oid *out)

View File

@ -4,8 +4,6 @@
#include "subagent.h" #include "subagent.h"
#include "mib_tree.h" #include "mib_tree.h"
uint snmp_pkt_len(const byte *start, const byte *end);
/* /*
* *
* AgentX Variable Biding (VarBind) utils * AgentX Variable Biding (VarBind) utils
@ -27,7 +25,6 @@ int snmp_oid_is_prefixable(const struct oid *oid);
uint snmp_oid_size(const struct oid *o); uint snmp_oid_size(const struct oid *o);
size_t snmp_oid_size_from_len(uint n_subid); size_t snmp_oid_size_from_len(uint n_subid);
void snmp_oid_copy(struct oid *dest, const struct oid *src); void snmp_oid_copy(struct oid *dest, const struct oid *src);
void snmp_oid_copy2(struct oid *dest, const struct oid *src);
int snmp_oid_compare(const struct oid *first, const struct oid *second); int snmp_oid_compare(const struct oid *first, const struct oid *second);
void snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct oid *result); void snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct oid *result);
void snmp_oid_from_buf(struct oid *dest, const struct oid *src); void snmp_oid_from_buf(struct oid *dest, const struct oid *src);
@ -49,28 +46,27 @@ snmp_oid_is_prefixed(const struct oid *oid)
/* type IPv4 */ /* type IPv4 */
int snmp_valid_ip4_index(const struct oid *o, uint start); int snmp_valid_ip4_index(const struct oid *o, uint start);
int snmp_valid_ip4_index_unsafe(const struct oid *o, uint start); int snmp_valid_ip4_index_unsafe(const struct oid *o, uint start);
void snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr);
/* /*
* AgentX - Variable Binding (VarBind) manupulation * AgentX - Variable Binding (VarBind) manupulation
*/ */
uint snmp_varbind_header_size(const struct oid *vb_name); uint snmp_varbind_header_size(const struct oid *vb_name);
uint snmp_varbind_size(const struct agentx_varbind *vb, uint limit);
uint snmp_varbind_size_unsafe(const struct agentx_varbind *vb); uint snmp_varbind_size_unsafe(const struct agentx_varbind *vb);
size_t snmp_varbind_size_from_len(uint n_subid, enum agentx_type t, uint len); size_t snmp_varbind_size_from_len(uint n_subid, enum agentx_type t, uint len);
int snmp_test_varbind_type(u16 type); int snmp_test_varbind_type(u16 type);
void *snmp_varbind_data(const struct agentx_varbind *vb); void *snmp_varbind_data(const struct agentx_varbind *vb);
struct oid *snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len);
void snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb);
/* /*
* AgentX - PDU headers, types, contexts * AgentX - PDU headers, types, contexts
*/ */
void snmp_session(const struct snmp_proto *p, struct agentx_header *h); void snmp_session(const struct snmp_proto *p, struct agentx_header *h);
int snmp_has_context(const struct agentx_header *h);
void snmp_pdu_context(struct snmp_pdu *pdu, struct snmp_proto *p, sock *sk); void snmp_pdu_context(struct snmp_pdu *pdu, struct snmp_proto *p, sock *sk);
struct oid *snmp_oid_duplicate(pool *pool, const struct oid *oid);
struct oid *snmp_oid_blank(struct snmp_proto *p); static inline int
snmp_has_context(const struct agentx_header *h)
{
return LOAD_U8(h->flags) & AGENTX_NON_DEFAULT_CONTEXT;
}
int snmp_test_close_reason(byte value); int snmp_test_close_reason(byte value);
@ -105,7 +101,6 @@ byte *snmp_put_fbyte(byte *buf, u8 data);
struct snmp_registration *snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib); struct snmp_registration *snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib);
int snmp_registration_match(struct snmp_registration *r, struct agentx_header *h); int snmp_registration_match(struct snmp_registration *r, struct agentx_header *h);
void snmp_dump_packet(byte *pkt, uint size);
void snmp_oid_dump(const struct oid *oid); void snmp_oid_dump(const struct oid *oid);
void snmp_oid_log(const struct oid *oid); void snmp_oid_log(const struct oid *oid);

File diff suppressed because it is too large Load Diff

View File

@ -6,10 +6,6 @@
#include "snmp.h" #include "snmp.h"
#include "lib/macro.h" #include "lib/macro.h"
void snmp_start_subagent(struct snmp_proto *p);
void snmp_stop_subagent(struct snmp_proto *p);
void snmp_ping(struct snmp_proto *p);
#define AGENTX_VERSION 1 #define AGENTX_VERSION 1
/* standard snmp internet prefix */ /* standard snmp internet prefix */
@ -196,11 +192,6 @@ struct agentx_varbind {
/* AgentX variable binding data optionally here */ /* AgentX variable binding data optionally here */
}; };
struct agentx_search_range {
struct oid *start;
struct oid *end;
};
/* AgentX Octet String */ /* AgentX Octet String */
struct agentx_octet_str { struct agentx_octet_str {
u32 length; u32 length;
@ -333,6 +324,7 @@ struct snmp_pdu {
u32 index; /* index on which the error was found */ u32 index; /* index on which the error was found */
}; };
#if 0
struct snmp_packet_info { struct snmp_packet_info {
node n; node n;
u8 type; // enum type u8 type; // enum type
@ -341,14 +333,18 @@ struct snmp_packet_info {
u32 packet_id; u32 packet_id;
void *data; void *data;
}; };
#endif
void snmp_start_subagent(struct snmp_proto *p);
void snmp_stop_subagent(struct snmp_proto *p);
void snmp_ping(struct snmp_proto *p);
int snmp_rx(sock *sk, uint size); int snmp_rx(sock *sk, uint size);
void snmp_tx(sock *sk); void snmp_tx(sock *sk);
int snmp_rx_stop(sock *sk, uint size);
void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance); void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance);
void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len); void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len);
void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime); void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime);
void snmp_register_mibs(struct snmp_proto *p);
struct agentx_varbind *snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid);
int snmp_tbuf_reserve(struct snmp_pdu *c, size_t bytes); int snmp_tbuf_reserve(struct snmp_pdu *c, size_t bytes);
static inline int static inline int
@ -359,9 +355,5 @@ snmp_is_active(const struct snmp_proto *p)
p->state == SNMP_CONN; p->state == SNMP_CONN;
} }
struct agentx_varbind *snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid);
u8 snmp_get_mib_class(const struct oid *oid);
void snmp_register_mibs(struct snmp_proto *p);
#endif #endif