mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
SNMP: AgentX over UNIX-domain sockets
This commit is contained in:
parent
ea643215e2
commit
95438b7608
@ -31,7 +31,6 @@ snmp_proto:
|
||||
snmp_proto_item:
|
||||
proto_item
|
||||
| snmp_bgp_bond
|
||||
/* | INTERFACE snmp_interface TODO */
|
||||
| LOCAL PORT expr {
|
||||
if (($3 < 1) || ($3 > 65535)) cf_error("Invalid port number");
|
||||
SNMP_CFG->local_port = $3;
|
||||
@ -42,12 +41,31 @@ snmp_proto_item:
|
||||
}
|
||||
| LOCAL ID IP4 { SNMP_CFG->bgp_local_id = $3; }
|
||||
| LOCAL ADDRESS IP4 { SNMP_CFG->local_ip = $3; }
|
||||
| REMOTE ADDRESS DEFAULT {
|
||||
if (SNMP_CFG->trans_type != SNMP_TRANS_DEFAULT)
|
||||
cf_error("Duplicit option remote address");
|
||||
}
|
||||
| REMOTE ADDRESS IP4 {
|
||||
if (ip4_zero($3)) cf_error("Invalid remote ip address");
|
||||
if (SNMP_CFG->trans_type != SNMP_TRANS_DEFAULT)
|
||||
cf_error("Duplicit option remote address");
|
||||
|
||||
// TODO
|
||||
//if (ip4_zero($3)) cf_error("Invalid remote ip address");
|
||||
|
||||
SNMP_CFG->remote_ip = $3;
|
||||
SNMP_CFG->trans_type = SNMP_TRANS_TCP;
|
||||
}
|
||||
| REMOTE ADDRESS text {
|
||||
if (SNMP_CFG->trans_type != SNMP_TRANS_DEFAULT)
|
||||
cf_error("Duplicit option remote address");
|
||||
|
||||
if (strcmp($3, agentx_master_addr)) {
|
||||
SNMP_CFG->remote_path = $3;
|
||||
SNMP_CFG->trans_type = SNMP_TRANS_UNIX;
|
||||
}
|
||||
}
|
||||
| LOCAL AS expr {
|
||||
if ($3 < 1 || $3 > 65535) cf_error("Invalid local AS");
|
||||
if ($3 < 1 || $3 > UINT16_MAX) cf_error("Invalid local AS");
|
||||
SNMP_CFG->bgp_local_as = $3;
|
||||
}
|
||||
| SNMP DESCRIPTION text {
|
||||
@ -87,7 +105,9 @@ snmp_proto_start: proto_start SNMP
|
||||
SNMP_CFG->bonds = 0;
|
||||
|
||||
SNMP_CFG->local_ip = IP4_NONE;
|
||||
SNMP_CFG->remote_ip = ip4_build(127,0,0,1);
|
||||
SNMP_CFG->remote_ip = IP4_NONE;
|
||||
SNMP_CFG->remote_path = agentx_master_addr;
|
||||
SNMP_CFG->trans_type = SNMP_TRANS_DEFAULT;
|
||||
SNMP_CFG->bgp_local_id = IP4_NONE;
|
||||
SNMP_CFG->local_port = 0;
|
||||
SNMP_CFG->remote_port = 705;
|
||||
|
@ -122,6 +122,7 @@
|
||||
// TODO: remove me
|
||||
#include "proto/bgp/bgp.h"
|
||||
|
||||
const char agentx_master_addr[] = AGENTX_MASTER_ADDR;
|
||||
|
||||
static void snmp_start_locked(struct object_lock *lock);
|
||||
static void snmp_sock_err(sock *sk, int err);
|
||||
@ -170,6 +171,7 @@ int
|
||||
snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
||||
{
|
||||
enum snmp_proto_state last = p->state;
|
||||
const struct snmp_config *cf = (struct snmp_config *) p->p.cf;
|
||||
|
||||
TRACE(D_EVENTS, "SNMP changing state to %u", state);
|
||||
|
||||
@ -193,31 +195,50 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
||||
case SNMP_INIT:
|
||||
DBG("snmp -> SNMP_INIT\n");
|
||||
ASSERT(last == SNMP_DOWN);
|
||||
struct object_lock *lock;
|
||||
lock = p->lock = olock_new(p->pool);
|
||||
|
||||
/*
|
||||
* lock->addr
|
||||
* lock->port
|
||||
* lock->iface
|
||||
* lock->vrf
|
||||
*/
|
||||
lock->type = OBJLOCK_TCP;
|
||||
lock->hook = snmp_start_locked;
|
||||
lock->data = p;
|
||||
olock_acquire(lock);
|
||||
return PS_START;
|
||||
if (cf->trans_type == SNMP_TRANS_TCP)
|
||||
{
|
||||
/* We need to lock the IP address */
|
||||
struct object_lock *lock;
|
||||
lock = p->lock = olock_new(p->pool);
|
||||
|
||||
/*
|
||||
* lock->iface
|
||||
* lock->vrf
|
||||
*/
|
||||
lock->addr = ipa_from_ip4(cf->remote_ip);
|
||||
lock->port = cf->remote_port;
|
||||
lock->type = OBJLOCK_TCP;
|
||||
lock->hook = snmp_start_locked;
|
||||
lock->data = p;
|
||||
olock_acquire(lock);
|
||||
return PS_START;
|
||||
}
|
||||
|
||||
p->state = state = SNMP_LOCKED;
|
||||
/* Fall thru */
|
||||
|
||||
case SNMP_LOCKED:
|
||||
DBG("snmp -> SNMP_LOCKED\n");
|
||||
ASSERT(last == SNMP_INIT || SNMP_RESET);
|
||||
sock *s = sk_new(p->pool);
|
||||
s->type = SK_TCP_ACTIVE;
|
||||
s->saddr = ipa_from_ip4(p->local_ip);
|
||||
s->daddr = ipa_from_ip4(p->remote_ip);
|
||||
s->dport = p->remote_port;
|
||||
s->rbsize = SNMP_RX_BUFFER_SIZE;
|
||||
s->tbsize = SNMP_TX_BUFFER_SIZE;
|
||||
|
||||
if (cf->trans_type == SNMP_TRANS_TCP)
|
||||
{
|
||||
s->type = SK_TCP_ACTIVE;
|
||||
s->saddr = ipa_from_ip4(p->local_ip);
|
||||
s->daddr = ipa_from_ip4(p->remote_ip);
|
||||
s->dport = p->remote_port;
|
||||
s->rbsize = SNMP_RX_BUFFER_SIZE;
|
||||
s->tbsize = SNMP_TX_BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->type = SK_UNIX_ACTIVE;
|
||||
s->host = cf->remote_path; /* daddr */
|
||||
s->rbsize = SNMP_RX_BUFFER_SIZE;
|
||||
s->tbsize = SNMP_TX_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
/* s->tos = IP_PREC_INTERNET_CONTROL */
|
||||
s->tx_hook = snmp_connected;
|
||||
@ -241,12 +262,14 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
||||
p->sock->rx_hook = snmp_rx;
|
||||
p->sock->tx_hook = NULL;
|
||||
snmp_start_subagent(p);
|
||||
// handle no response (for long time)
|
||||
p->startup_timer->hook = snmp_stop_timeout;
|
||||
tm_start(p->startup_timer, 1 S);
|
||||
return PS_START;
|
||||
|
||||
case SNMP_REGISTER:
|
||||
DBG("snmp -> SNMP_REGISTER\n");
|
||||
ASSERT(last == SNMP_OPEN);
|
||||
tm_stop(p->startup_timer); /* stop timeout */
|
||||
snmp_register_mibs(p);
|
||||
return PS_START;
|
||||
|
||||
@ -276,6 +299,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
||||
DBG("snmp -> SNMP_RESET\n");
|
||||
ASSUME(last == SNMP_REGISTER || last == SNMP_CONN);
|
||||
ASSUME(p->sock);
|
||||
snmp_stop_subagent(p);
|
||||
p->sock->rx_hook = snmp_rx_skip;
|
||||
p->sock->tx_hook = snmp_tx_skip;
|
||||
return PS_STOP;
|
||||
@ -612,8 +636,10 @@ snmp_show_proto_info(struct proto *P)
|
||||
static void
|
||||
snmp_postconfig(struct proto_config *CF)
|
||||
{
|
||||
const struct snmp_config *cf = (struct snmp_config *) CF;
|
||||
|
||||
/* Walk the BGP protocols and cache their references. */
|
||||
if (((struct snmp_config *) CF)->bgp_local_as == 0)
|
||||
if (cf->bgp_local_as == 0)
|
||||
cf_error("local as not specified");
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define SNMP_TX_BUFFER_SIZE 8192
|
||||
#define SNMP_PKT_SIZE_MAX 4098
|
||||
|
||||
#define AGENTX_MASTER_ADDR "/var/agentx/master"
|
||||
|
||||
enum snmp_proto_state {
|
||||
SNMP_DOWN = 0,
|
||||
SNMP_INIT = 1,
|
||||
@ -46,12 +48,20 @@ struct snmp_bond {
|
||||
u8 type;
|
||||
};
|
||||
|
||||
enum snmp_transport_type {
|
||||
SNMP_TRANS_DEFAULT,
|
||||
SNMP_TRANS_UNIX,
|
||||
SNMP_TRANS_TCP,
|
||||
};
|
||||
|
||||
struct snmp_config {
|
||||
struct proto_config cf;
|
||||
enum snmp_transport_type trans_type;
|
||||
ip4_addr local_ip;
|
||||
ip4_addr remote_ip;
|
||||
u16 local_port;
|
||||
ip4_addr remote_ip; /* master agentx IP address for TCP transport */
|
||||
u16 remote_port;
|
||||
const char *remote_path; /* master agentx UNIX socket name */
|
||||
|
||||
ip4_addr bgp_local_id; /* BGP4-MIB related fields */
|
||||
u32 bgp_local_as;
|
||||
@ -67,7 +77,7 @@ struct snmp_config {
|
||||
* We use this fact to check differences of
|
||||
* nonallocated parts of configs with memcpy
|
||||
*/
|
||||
//const struct oid *oid_identifier; TODO
|
||||
//const struct oid *oid_identifier; TODO
|
||||
};
|
||||
|
||||
#define SNMP_BGP_P_REGISTERING 0x01
|
||||
@ -84,6 +94,7 @@ struct snmp_registered_oid {
|
||||
struct oid *oid;
|
||||
};
|
||||
|
||||
|
||||
struct snmp_proto {
|
||||
struct proto p;
|
||||
struct object_lock *lock;
|
||||
@ -153,4 +164,6 @@ int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state);
|
||||
|
||||
void snmp_reset(struct snmp_proto *p);
|
||||
|
||||
extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)];
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user