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;
}
| 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 {
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;
// 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);
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);
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;
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;
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;
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");
}
#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,
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;
* 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
struct oid *oid;
};
+
struct snmp_proto {
struct proto p;
struct object_lock *lock;
void snmp_reset(struct snmp_proto *p);
+extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)];
+
#endif