mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31: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:
|
snmp_proto_item:
|
||||||
proto_item
|
proto_item
|
||||||
| snmp_bgp_bond
|
| snmp_bgp_bond
|
||||||
/* | INTERFACE snmp_interface TODO */
|
|
||||||
| LOCAL PORT expr {
|
| LOCAL PORT expr {
|
||||||
if (($3 < 1) || ($3 > 65535)) cf_error("Invalid port number");
|
if (($3 < 1) || ($3 > 65535)) cf_error("Invalid port number");
|
||||||
SNMP_CFG->local_port = $3;
|
SNMP_CFG->local_port = $3;
|
||||||
@ -42,12 +41,31 @@ snmp_proto_item:
|
|||||||
}
|
}
|
||||||
| LOCAL ID IP4 { SNMP_CFG->bgp_local_id = $3; }
|
| LOCAL ID IP4 { SNMP_CFG->bgp_local_id = $3; }
|
||||||
| LOCAL ADDRESS IP4 { SNMP_CFG->local_ip = $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 {
|
| 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->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 {
|
| 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_CFG->bgp_local_as = $3;
|
||||||
}
|
}
|
||||||
| SNMP DESCRIPTION text {
|
| SNMP DESCRIPTION text {
|
||||||
@ -87,7 +105,9 @@ snmp_proto_start: proto_start SNMP
|
|||||||
SNMP_CFG->bonds = 0;
|
SNMP_CFG->bonds = 0;
|
||||||
|
|
||||||
SNMP_CFG->local_ip = IP4_NONE;
|
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->bgp_local_id = IP4_NONE;
|
||||||
SNMP_CFG->local_port = 0;
|
SNMP_CFG->local_port = 0;
|
||||||
SNMP_CFG->remote_port = 705;
|
SNMP_CFG->remote_port = 705;
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
// TODO: remove me
|
// TODO: remove me
|
||||||
#include "proto/bgp/bgp.h"
|
#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_start_locked(struct object_lock *lock);
|
||||||
static void snmp_sock_err(sock *sk, int err);
|
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)
|
snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
||||||
{
|
{
|
||||||
enum snmp_proto_state last = p->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);
|
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:
|
case SNMP_INIT:
|
||||||
DBG("snmp -> SNMP_INIT\n");
|
DBG("snmp -> SNMP_INIT\n");
|
||||||
ASSERT(last == SNMP_DOWN);
|
ASSERT(last == SNMP_DOWN);
|
||||||
struct object_lock *lock;
|
|
||||||
lock = p->lock = olock_new(p->pool);
|
|
||||||
|
|
||||||
/*
|
if (cf->trans_type == SNMP_TRANS_TCP)
|
||||||
* lock->addr
|
{
|
||||||
* lock->port
|
/* We need to lock the IP address */
|
||||||
* lock->iface
|
struct object_lock *lock;
|
||||||
* lock->vrf
|
lock = p->lock = olock_new(p->pool);
|
||||||
*/
|
|
||||||
lock->type = OBJLOCK_TCP;
|
/*
|
||||||
lock->hook = snmp_start_locked;
|
* lock->iface
|
||||||
lock->data = p;
|
* lock->vrf
|
||||||
olock_acquire(lock);
|
*/
|
||||||
return PS_START;
|
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:
|
case SNMP_LOCKED:
|
||||||
DBG("snmp -> SNMP_LOCKED\n");
|
DBG("snmp -> SNMP_LOCKED\n");
|
||||||
ASSERT(last == SNMP_INIT || SNMP_RESET);
|
ASSERT(last == SNMP_INIT || SNMP_RESET);
|
||||||
sock *s = sk_new(p->pool);
|
sock *s = sk_new(p->pool);
|
||||||
s->type = SK_TCP_ACTIVE;
|
|
||||||
s->saddr = ipa_from_ip4(p->local_ip);
|
if (cf->trans_type == SNMP_TRANS_TCP)
|
||||||
s->daddr = ipa_from_ip4(p->remote_ip);
|
{
|
||||||
s->dport = p->remote_port;
|
s->type = SK_TCP_ACTIVE;
|
||||||
s->rbsize = SNMP_RX_BUFFER_SIZE;
|
s->saddr = ipa_from_ip4(p->local_ip);
|
||||||
s->tbsize = SNMP_TX_BUFFER_SIZE;
|
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->tos = IP_PREC_INTERNET_CONTROL */
|
||||||
s->tx_hook = snmp_connected;
|
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->rx_hook = snmp_rx;
|
||||||
p->sock->tx_hook = NULL;
|
p->sock->tx_hook = NULL;
|
||||||
snmp_start_subagent(p);
|
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;
|
return PS_START;
|
||||||
|
|
||||||
case SNMP_REGISTER:
|
case SNMP_REGISTER:
|
||||||
DBG("snmp -> SNMP_REGISTER\n");
|
DBG("snmp -> SNMP_REGISTER\n");
|
||||||
ASSERT(last == SNMP_OPEN);
|
ASSERT(last == SNMP_OPEN);
|
||||||
|
tm_stop(p->startup_timer); /* stop timeout */
|
||||||
snmp_register_mibs(p);
|
snmp_register_mibs(p);
|
||||||
return PS_START;
|
return PS_START;
|
||||||
|
|
||||||
@ -276,6 +299,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
|
|||||||
DBG("snmp -> SNMP_RESET\n");
|
DBG("snmp -> SNMP_RESET\n");
|
||||||
ASSUME(last == SNMP_REGISTER || last == SNMP_CONN);
|
ASSUME(last == SNMP_REGISTER || last == SNMP_CONN);
|
||||||
ASSUME(p->sock);
|
ASSUME(p->sock);
|
||||||
|
snmp_stop_subagent(p);
|
||||||
p->sock->rx_hook = snmp_rx_skip;
|
p->sock->rx_hook = snmp_rx_skip;
|
||||||
p->sock->tx_hook = snmp_tx_skip;
|
p->sock->tx_hook = snmp_tx_skip;
|
||||||
return PS_STOP;
|
return PS_STOP;
|
||||||
@ -612,8 +636,10 @@ snmp_show_proto_info(struct proto *P)
|
|||||||
static void
|
static void
|
||||||
snmp_postconfig(struct proto_config *CF)
|
snmp_postconfig(struct proto_config *CF)
|
||||||
{
|
{
|
||||||
|
const struct snmp_config *cf = (struct snmp_config *) CF;
|
||||||
|
|
||||||
/* Walk the BGP protocols and cache their references. */
|
/* 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");
|
cf_error("local as not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#define SNMP_TX_BUFFER_SIZE 8192
|
#define SNMP_TX_BUFFER_SIZE 8192
|
||||||
#define SNMP_PKT_SIZE_MAX 4098
|
#define SNMP_PKT_SIZE_MAX 4098
|
||||||
|
|
||||||
|
#define AGENTX_MASTER_ADDR "/var/agentx/master"
|
||||||
|
|
||||||
enum snmp_proto_state {
|
enum snmp_proto_state {
|
||||||
SNMP_DOWN = 0,
|
SNMP_DOWN = 0,
|
||||||
SNMP_INIT = 1,
|
SNMP_INIT = 1,
|
||||||
@ -46,12 +48,20 @@ struct snmp_bond {
|
|||||||
u8 type;
|
u8 type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum snmp_transport_type {
|
||||||
|
SNMP_TRANS_DEFAULT,
|
||||||
|
SNMP_TRANS_UNIX,
|
||||||
|
SNMP_TRANS_TCP,
|
||||||
|
};
|
||||||
|
|
||||||
struct snmp_config {
|
struct snmp_config {
|
||||||
struct proto_config cf;
|
struct proto_config cf;
|
||||||
|
enum snmp_transport_type trans_type;
|
||||||
ip4_addr local_ip;
|
ip4_addr local_ip;
|
||||||
ip4_addr remote_ip;
|
|
||||||
u16 local_port;
|
u16 local_port;
|
||||||
|
ip4_addr remote_ip; /* master agentx IP address for TCP transport */
|
||||||
u16 remote_port;
|
u16 remote_port;
|
||||||
|
const char *remote_path; /* master agentx UNIX socket name */
|
||||||
|
|
||||||
ip4_addr bgp_local_id; /* BGP4-MIB related fields */
|
ip4_addr bgp_local_id; /* BGP4-MIB related fields */
|
||||||
u32 bgp_local_as;
|
u32 bgp_local_as;
|
||||||
@ -84,6 +94,7 @@ struct snmp_registered_oid {
|
|||||||
struct oid *oid;
|
struct oid *oid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct snmp_proto {
|
struct snmp_proto {
|
||||||
struct proto p;
|
struct proto p;
|
||||||
struct object_lock *lock;
|
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);
|
void snmp_reset(struct snmp_proto *p);
|
||||||
|
|
||||||
|
extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user