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

TMP: proto-snmp compiles and connects to master

This commit is contained in:
Vojtech Vilimek 2022-08-02 16:04:25 +02:00
parent f4dc719f14
commit e5a88b584e
8 changed files with 383 additions and 66 deletions

View File

@ -1,7 +1,8 @@
src := snmp.c src := snmp.c bgp_mib.c subagent.c
obj := $(src-o-files) obj := $(src-o-files)
LIBS += `net-snmp-config --agent-libs`
$(all-daemon) $(all-daemon)
$(cf-local) $(cf-local)
$(call proto-build,snmp_build) $(call proto-build,snmp_build_)
tests_objs := $(tests_objs) $(src-o-files) tests_objs := $(tests_objs) $(src-o-files)

133
proto/snmp/bgp_mib.c Normal file
View File

@ -0,0 +1,133 @@
/*
* BIRD -- Simple Network Management Protocol (SNMP)
* BGP4-MIB bgpPeerTable
*
* (c) 2022 Vojtech Vilimek <vojtech.vilimek@nic.cz>
* (c) 2022 CZ.NIC z.s.p.o
*
* Can be freely distributed and used under the terms of the GNU GPL.
*
* Parts of this file were auto-generated using mib2c
* using mib2c.create-dataset.conf
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/varbind_api.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
// fix conflicts
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include "proto/snmp/bgp_mib.h"
#include "lib/birdlib.h"
static int
bgpPeerTable_handler(
netsnmp_mib_handler *handler, // contains void * for internal use
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests) {
/* perform anything here that you need to do. The requests have
already been processed by the master table_dataset handler, but
this gives you chance to act on the request in some other way
if need be. */
log(L_INFO " bgpPeerTable_handler()");
// walk list of netsnmp_data_list
for (netsnmp_data_list *l = reqinfo->agent_data;
l; l->next)
{
log(L_INFO " name: %s, poniter %p", l->name, l->data);
}
char buff[64];
// walk list of netsnmp_variable_list VB
for (netsnmp_variable_list *var = requests->requestvb;
var; var->next_variable)
{
snprint_value(buff, 64, var->name, var->name_length, var);
log(L_INFO "variable %s", buff);
memset((void *) buff, 0, 64);
}
return SNMP_ERR_NOERROR;
}
void
snmp_init_bgp_table(void)
{
const oid bgpPeerTable_oid[] = {1,3,6,1,2,1,15,3};
netsnmp_table_data_set *table_set;
/* create the table structure itself */
table_set = netsnmp_create_table_data_set("bgpPeerTable");
log(L_INFO "adding indexes to SNMP table bgpPeerTable");
netsnmp_table_set_add_indexes(
table_set,
ASN_IPADDRESS, /* index: bgpPeerRemoteAddr */
0
);
log(L_INFO "adding column types to SNMP table bgpPeerTable");
netsnmp_table_set_multi_add_default_row(
table_set,
SNMP_BGP_IDENTIFIER, ASN_IPADDRESS, 0, NULL, 0,
SNMP_BGP_STATE, ASN_INTEGER, 0, NULL, 0,
/* change to ASN_INTEGER, 1, NULL, 0, below to allow write */
SNMP_BGP_ADMIN_STATUS, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_VERSION, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_LOCAL_ADDR, ASN_IPADDRESS, 0, NULL, 0,
SNMP_BGP_LOCAL_PORT, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_REMOTE_ADDR, ASN_IPADDRESS, 0, NULL, 0,
SNMP_BGP_REMOTE_PORT, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_REMOTE_AS, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_RX_UPDATES, ASN_COUNTER, 0, NULL, 0,
SNMP_BGP_TX_UPDATES, ASN_COUNTER, 0, NULL, 0,
SNMP_BGP_RX_MESSAGES, ASN_COUNTER, 0, NULL, 0,
SNMP_BGP_TX_MESSAGES, ASN_COUNTER, 0, NULL, 0,
SNMP_BGP_LAST_ERROR, ASN_OCTET_STR, 0, NULL, 0,
SNMP_BGP_FSM_TRANSITIONS, ASN_COUNTER, 0, NULL, 0,
SNMP_BGP_FSM_ESTABLISHED_TIME, ASN_GAUGE, 0, NULL, 0,
SNMP_BGP_RETRY_INTERVAL, ASN_INTEGER, 1, NULL, 0,
SNMP_BGP_HOLD_TIME, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_KEEPALIVE, ASN_INTEGER, 0, NULL, 0,
SNMP_BGP_HOLD_TIME_CONFIGURED, ASN_INTEGER, 1, NULL, 0,
SNMP_BGP_KEEPALIVE_CONFIGURED, ASN_INTEGER, 1, NULL, 0,
SNMP_BGP_ORIGINATION_INTERVAL, ASN_INTEGER, 1, NULL, 0,
SNMP_BGP_MIN_ROUTE_ADVERTISEMENT, ASN_INTEGER, 1, NULL, 0,
SNMP_BGP_MIN_UPDATE_ELAPSED_TIME, ASN_GAUGE, 0, NULL, 0,
0
);
/* registering the table with the master agent */
/* note: if you don't need a subhandler to deal with any aspects
of the request, change bgpPeerTable_handler to "NULL" */
netsnmp_register_table_data_set(
netsnmp_create_handler_registration(
"bgpPeerTable", bgpPeerTable_handler,
bgpPeerTable_oid,
OID_LENGTH(bgpPeerTable_oid),
HANDLER_CAN_RONLY
// HANDLER_CAN_RWRITE
),
table_set, NULL
);
}
void
snmp_del_bgp_table(void)
{
// XXX really needed ?
const oid bgpPeerTable_oid[] = {1,3,6,1,2,1,15,3};
remove_tree_entry(bgpPeerTable_oid, OID_LENGTH(bgpPeerTable_oid));
}

33
proto/snmp/bgp_mib.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef _BIRD_SNMP_BGP_MIB_H_
#define _BIRD_SNMP_BGP_MIB_H_
/* peers attributes */
#define SNMP_BGP_IDENTIFIER 1
#define SNMP_BGP_STATE 2
#define SNMP_BGP_ADMIN_STATUS 3 /* in read-only mode */
#define SNMP_BGP_VERSION 4
#define SNMP_BGP_LOCAL_ADDR 5
#define SNMP_BGP_LOCAL_PORT 6
#define SNMP_BGP_REMOTE_ADDR 7
#define SNMP_BGP_REMOTE_PORT 8
#define SNMP_BGP_REMOTE_AS 9
#define SNMP_BGP_RX_UPDATES 10 /* in updates */
#define SNMP_BGP_TX_UPDATES 11 /* out updates */
#define SNMP_BGP_RX_MESSAGES 12 /* in total messages */
#define SNMP_BGP_TX_MESSAGES 13 /* out total messages */
#define SNMP_BGP_LAST_ERROR 14 /* UNSUPPORTED */
#define SNMP_BGP_FSM_TRANSITIONS 15 /* FSM established transitions */
#define SNMP_BGP_FSM_ESTABLISHED_TIME 16 /* UNSUPPORTED FSM established time */
#define SNMP_BGP_RETRY_INTERVAL 17
#define SNMP_BGP_HOLD_TIME 18
#define SNMP_BGP_KEEPALIVE 19
#define SNMP_BGP_HOLD_TIME_CONFIGURED 20
#define SNMP_BGP_KEEPALIVE_CONFIGURED 21
#define SNMP_BGP_ORIGINATION_INTERVAL 22 /* UNSUPPORTED */
#define SNMP_BGP_MIN_ROUTE_ADVERTISEMENT 23 /* UNSUPPORTED */
#define SNMP_BGP_MIN_UPDATE_ELAPSED_TIME 24 /* UNSUPPORTED */
void snmp_init_bgp_table(void);
void snmp_del_bgp_table(void);
#endif

View File

@ -20,8 +20,6 @@ CF_DECLS
CF_KEYWORDS(SNMP, TABLE, PROTOCOL, BPG) CF_KEYWORDS(SNMP, TABLE, PROTOCOL, BPG)
%type <cc> snmp_channel_start
CF_GRAMMAR CF_GRAMMAR
proto: snmp_proto '}' { this_channel = NULL; } ; proto: snmp_proto '}' { this_channel = NULL; } ;
@ -29,47 +27,30 @@ proto: snmp_proto '}' { this_channel = NULL; } ;
snmp_proto: snmp_proto:
snmp_proto_start '{' snmp_proto_start '{'
| snmp_proto proto_item ';' | snmp_proto proto_item ';'
| snmp_proto snmp_proto_channel ';' | snmp_proto snmp_bgp_bond ';'
| snmp_proto ';' | snmp_proto ';'
; ;
snmp_proto_start: proto_start SNMP snmp_proto_start: proto_start SNMP
{ {
this_proto = proto_config_new(&proto_snmp, $1); this_proto = proto_config_new(&proto_snmp, $1);
init_list(&SNMP_CFG->bgp_entries);
} }
snmp_proto_channel: snmp_channel_start snmp_channel_opt_list channel_end ; snmp_bgp_bond: BGP symbol
snmp_channel_start: net_type symbol
{ {
this_channel = channel_config_get(&channel_snmp, $2->name, $1, this_proto); struct snmp_bond *this_bond = cfg_alloc(sizeof(struct snmp_bond));
this_bond->type = SNMP_BGP;
struct proto_config *pc;
WALK_LIST(pc, this_proto->global->protos)
if (!strcmp(pc->name, $2->name) && pc->protocol == &proto_bgp)
this_bond->proto = pc;
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);
add_tail(&SNMP_CFG->bgp_entries, (node *) this_bond);
} }
snmp_channel_opt_list:
/* empty */
| '{' snmp_opts '}'
;
snmp_opts:
/* empty */
| snmp_opts channel_item ';'
| snmp_opts snmp_opt ';'
;
snmp_opt:
PROTOCOL BGP symbol {
SNMP_CC->bgp = NULL;
struct proto_config *pc;
WALK_LIST(pc, this_proto->global->protos)
if (!strcmp(pc->name, $3->name)
&& pc->protocol == &proto_bgp)
SNMP_CC->bgp = (struct bgp_config *) pc;
if (!SNMP_CC->bgp) cf_error("BGP protocol %s not found", $3);
}
;
CF_CODE CF_CODE
CF_END CF_END

View File

@ -5,6 +5,9 @@
* (c) 2022 CZ.NIC z.s.p.o. * (c) 2022 CZ.NIC z.s.p.o.
* *
* Can be freely distributed and used under the terms of the GNU GPL. * Can be freely distributed and used under the terms of the GNU GPL.
*
* Parts of this file were auto-generated using mib2c
* using mib2c.create-dataset.conf
*/ */
#include "nest/bird.h" #include "nest/bird.h"
@ -12,6 +15,8 @@
#include "nest/cli.h" #include "nest/cli.h"
#include "proto/snmp/snmp.h" #include "proto/snmp/snmp.h"
#include "proto/snmp/subagent.h"
#include "proto/snmp/bgp_mib.h"
static struct proto * static struct proto *
snmp_init(struct proto_config *CF) snmp_init(struct proto_config *CF)
@ -24,17 +29,23 @@ snmp_init(struct proto_config *CF)
return P; return P;
} }
void start_multihook(void)
{
/* init bgp MIB table */
snmp_init_bgp_table();
/* init ospf MIB table */
//snmp_inti_ospf_table();
}
static int static int
snmp_start(struct proto *P) snmp_start(struct proto *P)
{ {
struct channel_config *cc; /* init MIB tables */
WALK_LIST(cc, P->cf->channels) if (snmp_start_subagent(start_multihook))
{ return PS_UP;
struct channel *c = NULL; else
proto_configure_channel(P, &c, cc); return PS_DOWN;
}
return PS_UP;
} }
static int static int
@ -46,42 +57,83 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
static void static void
snmp_show_proto_info(struct proto *P) snmp_show_proto_info(struct proto *P)
{ {
//struct stats_proto *p = (void *) P; struct snmp_proto *sp = (void *) P;
struct snmp_config *c = (void *) P->cf;
struct snmp_channel *sc; cli_msg(-1006, " BGP peers");
struct snmp_bond *bond;
WALK_LIST(sc, P->channels) WALK_LIST(bond, c->bgp_entries)
{ {
cli_msg(-1006, " Channel %s", sc->c.name); struct proto_config *cf = P->cf;
struct bgp_config *bcf = (struct bgp_config *) cf;
struct proto_config *pcf = (void *) bond->proto;
struct proto *p = cf->proto;
struct bgp_proto *bp = (struct bgp_proto *) cf->proto;
struct bgp_conn *conn = bp->conn;
if (!P->disabled) cli_msg(-1006, " name: %s", cf->name);
{ cli_msg(-1006, "");
cli_msg(-1006, " enabled"); cli_msg(-1006, " rem. identifier: %u", bp->remote_id);
// learn more !!
cli_msg(-1006, " admin status: %s", (p->disabled) ? "start" :
"stop");
// version ?
cli_msg(-1006, " version: ??, likely 4");
cli_msg(-1006, " local ip: %u", bcf->local_ip);
cli_msg(-1006, " remote ip: %u", bcf->remote_ip);
cli_msg(-1006, " local port: %u", bcf->local_port);
cli_msg(-1006, " remote port: %u", bcf->remote_port);
if (conn) {
cli_msg(-1006, " state: %u", conn->state);
cli_msg(-1006, " remote as: %u", conn->remote_caps->as4_number);
} }
else cli_msg(-1006, " in updates: %u", bp->stats.rx_updates);
cli_msg(-1006, " disabled"); cli_msg(-1006, " out updates: %u", bp->stats.tx_updates);
cli_msg(-1006, " in total: %u", bp->stats.rx_messages);
cli_msg(-1006, " out total: %u", bp->stats.tx_messages);
cli_msg(-1006, " fsm transitions: %u",
bp->stats.fsm_established_transitions);
// not supported yet
cli_msg(-1006, " fsm total time: --");
cli_msg(-1006, " retry interval: %u", bcf->connect_retry_time);
if (conn) {
cli_msg(-1006, " hold time: %u", conn->hold_time);
cli_msg(-1006, " keep alive: %u", conn->keepalive_time );
}
cli_msg(-1006, " hold configurated: %u", bcf->hold_time );
cli_msg(-1006, " keep alive config: %u", bcf->keepalive_time );
// unknown
cli_msg(-1006, " min AS origin. int.: --");
cli_msg(-1006, " min route advertisement: %u", 0 );
cli_msg(-1006, " in update elapsed time: %u", 0 );
if (!conn)
cli_msg(-1006, " no default connection");
cli_msg(-1006, " outgoinin_conn state %u", bp->outgoing_conn.state + 1);
cli_msg(-1006, " incoming_conn state: %u", bp->incoming_conn.state + 1);
} }
} }
static int
snmp_channel_start(struct channel *C) void
shutdown_multihook(void)
{ {
return 0; snmp_del_bgp_table();
//snmp_del_ospf_table();
} }
static void /* snmp_shutdown already occupied by net-snmp */
snmp_channel_shutdown(struct channel *C) void
snmp_shutdown_(struct proto *P)
{ {
snmp_stop_subagent(shutdown_multihook);
} }
struct channel_class channel_snmp = {
.channel_size = sizeof(struct snmp_channel),
.config_size = sizeof(struct snmp_channel_config),
.start = snmp_channel_start,
.shutdown = snmp_channel_shutdown,
};
struct protocol proto_snmp = { struct protocol proto_snmp = {
.name = "Snmp", .name = "Snmp",
.template = "snmp%d", .template = "snmp%d",
@ -91,11 +143,13 @@ 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,
}; };
/* strange name because conflict with net-snmp lib snmp_lib() */
void void
snmp_build(void) snmp_build_(void)
{ {
proto_build(&proto_snmp); proto_build(&proto_snmp);
} }

View File

@ -12,8 +12,20 @@
#include "proto/bgp/bgp.h" #include "proto/bgp/bgp.h"
#define SNMP_UNDEFINED 0
#define SNMP_BGP 1
#define SNMP_OSPF 2
#define SNMP_INVALID 255
struct snmp_bond {
node n;
struct proto_config *proto;
u8 type;
};
struct snmp_config { struct snmp_config {
struct channel_config c; struct channel_config c;
list bgp_entries;
}; };
struct snmp_proto { struct snmp_proto {
@ -24,6 +36,7 @@ struct snmp_proto {
struct snmp_channel_config { struct snmp_channel_config {
struct channel_config c; struct channel_config c;
struct bgp_config *bgp; struct bgp_config *bgp;
u8 type;
}; };
struct snmp_channel { struct snmp_channel {

94
proto/snmp/subagent.c Normal file
View File

@ -0,0 +1,94 @@
/*
* BIRD -- Simple Network Management Protocol (SNMP)
*
* (c) 2022 Vojtech Vilimek <vojtech.vilimek@nic.cz>
* (c) 2022 CZ.NIC z.s.p.o
*
* Can be freely distributed and used under the terms of the GNU GPL.
*
* Parts of this file were auto-generated from net-snmp-config
*/
#include <net-snmp/net-snmp-config.h>
#ifdef HAVE_SIGNAL
#include <signal.h>
#endif
#ifdef HAV_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
extern int netsnmp_running;
int
snmp_start_subagent(void (*hook)(void))
{
/* subagent mode */
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_ROLE, 1);
/* forking netsnmp mechanism * /
if (netsnmp_daemonize(1, snmp_stderrolog_status()) != 0)
return 0; // start FAILED
*/
/* for Win32 only */
SOCK_STARTUP;
/* init library */
init_agent("bird");
if (hook)
hook();
/* used for loading config 'bird-snmp.conf' */
init_snmp("bird-snmp");
return 1; // SUCCESS
}
void
snmp_agent_reconfigure(void)
{
free_config();
read_configs();
}
void
snmp_shutdown_subagent(void (*hook)(void))
{
/* at shutdown time */
snmp_shutdown("bird");
/* shutdown hook */
if (hook)
hook();
/* shutdown the agent library */
shutdown_agent();
/* for Win32 only */
SOCK_CLEANUP;
}
void
snmp_stop_subagent(void (*hook)(void))
{
/* at shutdown time */
snmp_shutdown("bird");
/* deinitialize MIB code */
if (hook)
hook();
/* shutdown the agent library */
shutdown_agent();
}

8
proto/snmp/subagent.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _BIRD_SNMP_SUBAGENT_H_
#define _BIRD_SNMP_SUBAGENT_H_
int snmp_start_subagent(void (*hook)(void));
void snmp_agent_reconfigure(void);
void snmp_stop_subagent(void (*hook)(void));
#endif